Commit 3f6677f4 by Nathan Sidwell Committed by Nathan Sidwell

[PATCH] CPP Macro predicates

https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00897.html
	libcpp/
	* include/cpplib.h (cpp_user_macro_p, cpp_builtin_macro_p)
	(cpp_macro_p): New inlines.
	* directives.c (do_pragma_poison): Use cpp_macro_p.
	(do_ifdef, do_ifndef): Likewise.  Use _cpp_maybe_notify_macro_use.
	(cpp_pop_definition): Use cpp_macro_p.  Move _cpp_free_definition
	earlier.  Don't zap node directly.
	* expr.c (parse_defined): Use _cpp_maybe_notify_macro_use &
	cpp_macro_p.
	* files.c (should_stack_file): Use cpp_macro_p.
	* identifiers.c (cpp_defined): Likewise.
	* internal.h (_cpp_mark_macro): Use cpp_user_macro_p.
	(_cpp_notify_macro_use): Declare.
	(_cpp_maybe_notify_macro_use): New inline.
	* lex.c (is_macro): Use cpp_macro_p.
	* macro.c (_cpp_warn_if_unused_macro): Use cpp_user_macro_p.
	(enter_macro_context): Likewise.
	(_cpp_create_definition): Use cpp_builtin_macro_p,
	cpp_user_macro_p.  Move _cpp_free_definition earlier.
	(_cpp_notify_macro_use): New, broken out of multiple call sites.
	* traditional.c (fun_like_macro_p): Use cpp_builtin_macro_p.
	(maybe_start_funlike, _cpp_scan_out_logical_line)
	(push_replacement_text): Likewise.
	gcc/c-family/
	* c-ada-spec.c (count_ada_macro): Use cpp_user_macro_p.
	(store_ada_macro): Likewise.
	* c-ppoutput.c (cb_used_define, dump_macro): Likewise.
	* c-spellcheck.cc (should-suggest_as_macro_p): Likewise,
	gcc/
	* config/rs6000/rs6000-c.c (rs6000_macro_to_expend): Use cpp_macro_p.
	* config/powerpcspc/powerpcspe-c.c (rs6000_macro_to_expend): Likewise.
	gcc/cp/
	* name-lookup.c (lookup_name_fuzzy): Likewise.
	gcc/fortran/
	* cpp.c (dump_macro): Use cpp_user_macro_p.

From-SVN: r263587
parent ba9d634f
2018-08-16 Nathan Sidwell <nathan@acm.org>
* config/rs6000/rs6000-c.c (rs6000_macro_to_expend): Use cpp_macro_p.
* config/powerpcspc/powerpcspe-c.c (rs6000_macro_to_expend): Likewise.
2018-08-16 Tamar Christina <tamar.christina@arm.com> 2018-08-16 Tamar Christina <tamar.christina@arm.com>
PR target/84711 PR target/84711
......
2018-08-16 Nathan Sidwell <nathan@acm.org>
* c-ada-spec.c (count_ada_macro): Use cpp_user_macro_p.
(store_ada_macro): Likewise.
* c-ppoutput.c (cb_used_define, dump_macro): Likewise.
* c-spellcheck.cc (should-suggest_as_macro_p): Likewise,
2018-08-15 David Malcolm <dmalcolm@redhat.com> 2018-08-15 David Malcolm <dmalcolm@redhat.com>
* c-format.c: Include "selftest-diagnostic.h" and * c-format.c: Include "selftest-diagnostic.h" and
......
...@@ -171,13 +171,12 @@ static int ...@@ -171,13 +171,12 @@ static int
count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node, count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node,
void *v ATTRIBUTE_UNUSED) void *v ATTRIBUTE_UNUSED)
{ {
const cpp_macro *macro = node->value.macro; if (cpp_user_macro_p (node) && *NODE_NAME (node) != '_')
{
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN) const cpp_macro *macro = node->value.macro;
&& macro->count if (macro->count && LOCATION_FILE (macro->line) == macro_source_file)
&& *NODE_NAME (node) != '_' max_ada_macros++;
&& LOCATION_FILE (macro->line) == macro_source_file) }
max_ada_macros++;
return 1; return 1;
} }
...@@ -190,15 +189,13 @@ static int ...@@ -190,15 +189,13 @@ static int
store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED,
cpp_hashnode *node, void *macros) cpp_hashnode *node, void *macros)
{ {
const cpp_macro *macro = node->value.macro; if (cpp_user_macro_p (node) && *NODE_NAME (node) != '_')
{
if (node->type == NT_MACRO const cpp_macro *macro = node->value.macro;
&& !(node->flags & NODE_BUILTIN) if (macro->count
&& macro->count && LOCATION_FILE (macro->line) == macro_source_file)
&& *NODE_NAME (node) != '_' ((cpp_hashnode **) macros)[store_ada_macro_index++] = node;
&& LOCATION_FILE (macro->line) == macro_source_file) }
((cpp_hashnode **) macros)[store_ada_macro_index++] = node;
return 1; return 1;
} }
......
...@@ -532,13 +532,14 @@ static void ...@@ -532,13 +532,14 @@ static void
cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED, cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED,
cpp_hashnode *node) cpp_hashnode *node)
{ {
macro_queue *q; if (cpp_user_macro_p (node))
if (node->flags & NODE_BUILTIN) {
return; macro_queue *q;
q = XNEW (macro_queue); q = XNEW (macro_queue);
q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node)); q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node));
q->next = define_queue; q->next = define_queue;
define_queue = q; define_queue = q;
}
} }
static void static void
...@@ -688,7 +689,7 @@ cb_def_pragma (cpp_reader *pfile, source_location line) ...@@ -688,7 +689,7 @@ cb_def_pragma (cpp_reader *pfile, source_location line)
static int static int
dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
{ {
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) if (cpp_user_macro_p (node))
{ {
fputs ("#define ", print.outf); fputs ("#define ", print.outf);
fputs ((const char *) cpp_macro_definition (pfile, node), fputs ((const char *) cpp_macro_definition (pfile, node),
......
...@@ -45,13 +45,13 @@ name_reserved_for_implementation_p (const char *str) ...@@ -45,13 +45,13 @@ name_reserved_for_implementation_p (const char *str)
static bool static bool
should_suggest_as_macro_p (cpp_hashnode *hashnode) should_suggest_as_macro_p (cpp_hashnode *hashnode)
{ {
if (hashnode->type != NT_MACRO) if (!cpp_macro_p (hashnode))
return false; return false;
/* Don't suggest names reserved for the implementation, but do suggest the builtin /* Don't suggest names reserved for the implementation, but do
macros such as __FILE__, __LINE__ etc. */ suggest the builtin macros such as __FILE__, __LINE__ etc. */
if (name_reserved_for_implementation_p ((const char *)hashnode->ident.str) if (cpp_user_macro_p (hashnode)
&& !(hashnode->flags & NODE_BUILTIN)) && name_reserved_for_implementation_p ((const char *)hashnode->ident.str))
return false; return false;
return true; return true;
......
...@@ -220,21 +220,22 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) ...@@ -220,21 +220,22 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword))) else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword)))
{ {
enum rid rid_code = (enum rid)(ident->rid_code); enum rid rid_code = (enum rid)(ident->rid_code);
enum node_type itype = ident->type; bool is_macro = cpp_macro_p (ident);
/* If there is a function-like macro, check if it is going to be /* If there is a function-like macro, check if it is going to be
invoked with or without arguments. Without following ( treat invoked with or without arguments. Without following ( treat
it like non-macro, otherwise the following cpp_get_token eats it like non-macro, otherwise the following cpp_get_token eats
what should be preserved. */ what should be preserved. */
if (itype == NT_MACRO && cpp_fun_like_macro_p (ident)) if (is_macro && cpp_fun_like_macro_p (ident))
{ {
int idx2 = idx; int idx2 = idx;
do do
tok = cpp_peek_token (pfile, idx2++); tok = cpp_peek_token (pfile, idx2++);
while (tok->type == CPP_PADDING); while (tok->type == CPP_PADDING);
if (tok->type != CPP_OPEN_PAREN) if (tok->type != CPP_OPEN_PAREN)
itype = NT_VOID; is_macro = false;
} }
if (itype == NT_MACRO) if (is_macro)
{ {
do do
(void) cpp_get_token (pfile); (void) cpp_get_token (pfile);
......
...@@ -220,21 +220,23 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) ...@@ -220,21 +220,23 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword))) else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword)))
{ {
enum rid rid_code = (enum rid)(ident->rid_code); enum rid rid_code = (enum rid)(ident->rid_code);
enum node_type itype = ident->type; bool is_macro = cpp_macro_p (ident);
/* If there is a function-like macro, check if it is going to be /* If there is a function-like macro, check if it is going to be
invoked with or without arguments. Without following ( treat invoked with or without arguments. Without following ( treat
it like non-macro, otherwise the following cpp_get_token eats it like non-macro, otherwise the following cpp_get_token eats
what should be preserved. */ what should be preserved. */
if (itype == NT_MACRO && cpp_fun_like_macro_p (ident)) if (is_macro && cpp_fun_like_macro_p (ident))
{ {
int idx2 = idx; int idx2 = idx;
do do
tok = cpp_peek_token (pfile, idx2++); tok = cpp_peek_token (pfile, idx2++);
while (tok->type == CPP_PADDING); while (tok->type == CPP_PADDING);
if (tok->type != CPP_OPEN_PAREN) if (tok->type != CPP_OPEN_PAREN)
itype = NT_VOID; is_macro = false;
} }
if (itype == NT_MACRO)
if (is_macro)
{ {
do do
(void) cpp_get_token (pfile); (void) cpp_get_token (pfile);
......
...@@ -5954,10 +5954,10 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc) ...@@ -5954,10 +5954,10 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc)
/* If we have an exact match for a macro name, then either the /* If we have an exact match for a macro name, then either the
macro was used with the wrong argument count, or the macro macro was used with the wrong argument count, or the macro
has been used before it was defined. */ has been used before it was defined. */
cpp_hashnode *macro = bmm.blithely_get_best_candidate (); if (cpp_hashnode *macro = bmm.blithely_get_best_candidate ())
if (macro && (macro->flags & NODE_BUILTIN) == 0) if (cpp_user_macro_p (macro))
return name_hint (NULL, return name_hint (NULL,
macro_use_before_def::maybe_make (loc, macro)); macro_use_before_def::maybe_make (loc, macro));
} }
/* Try the "starts_decl_specifier_p" keywords to detect /* Try the "starts_decl_specifier_p" keywords to detect
......
2018-08-16 Nathan Sidwell <nathan@acm.org>
* cpp.c (dump_macro): Use cpp_user_macro_p.
2018-08-14 Janus Weil <janus@gcc.gnu.org> 2018-08-14 Janus Weil <janus@gcc.gnu.org>
PR fortran/86116 PR fortran/86116
......
...@@ -990,7 +990,7 @@ cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, ...@@ -990,7 +990,7 @@ cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
static int static int
dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
{ {
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) if (cpp_user_macro_p (node))
{ {
fputs ("#define ", print.outf); fputs ("#define ", print.outf);
fputs ((const char *) cpp_macro_definition (pfile, node), fputs ((const char *) cpp_macro_definition (pfile, node),
......
2018-08-16 Nathan Sidwell <nathan@acm.org>
libcpp/
* include/cpplib.h (cpp_user_macro_p, cpp_builtin_macro_p)
(cpp_macro_p): New inlines.
* directives.c (do_pragma_poison): Use cpp_macro_p.
(do_ifdef, do_ifndef): Likewise. Use _cpp_maybe_notify_macro_use.
(cpp_pop_definition): Use cpp_macro_p. Move _cpp_free_definition
earlier. Don't zap node directly.
* expr.c (parse_defined): Use _cpp_maybe_notify_macro_use &
cpp_macro_p.
* files.c (should_stack_file): Use cpp_macro_p.
* identifiers.c (cpp_defined): Likewise.
* internal.h (_cpp_mark_macro): Use cpp_user_macro_p.
(_cpp_notify_macro_use): Declare.
(_cpp_maybe_notify_macro_use): New inline.
* lex.c (is_macro): Use cpp_macro_p.
* macro.c (_cpp_warn_if_unused_macro): Use cpp_user_macro_p.
(enter_macro_context): Likewise.
(_cpp_create_definition): Use cpp_builtin_macro_p,
cpp_user_macro_p. Move _cpp_free_definition earlier.
(_cpp_notify_macro_use): New, broken out of multiple call sites.
* traditional.c (fun_like_macro_p): Use cpp_builtin_macro_p.
(maybe_start_funlike, _cpp_scan_out_logical_line)
(push_replacement_text): Likewise.
2018-08-15 David Malcolm <dmalcolm@redhat.com> 2018-08-15 David Malcolm <dmalcolm@redhat.com>
* include/line-map.h (struct location_range): Add "m_label" field. * include/line-map.h (struct location_range): Add "m_label" field.
......
...@@ -1666,7 +1666,7 @@ do_pragma_poison (cpp_reader *pfile) ...@@ -1666,7 +1666,7 @@ do_pragma_poison (cpp_reader *pfile)
if (hp->flags & NODE_POISONED) if (hp->flags & NODE_POISONED)
continue; continue;
if (hp->type == NT_MACRO) if (cpp_macro_p (hp))
cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"", cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"",
NODE_NAME (hp)); NODE_NAME (hp));
_cpp_free_definition (hp); _cpp_free_definition (hp);
...@@ -1960,26 +1960,9 @@ do_ifdef (cpp_reader *pfile) ...@@ -1960,26 +1960,9 @@ do_ifdef (cpp_reader *pfile)
the powerpc and spu ports using conditional macros for 'vector', the powerpc and spu ports using conditional macros for 'vector',
'bool', and 'pixel' to act as conditional keywords. This messes 'bool', and 'pixel' to act as conditional keywords. This messes
up tests like #ifndef bool. */ up tests like #ifndef bool. */
skip = (node->type != NT_MACRO skip = !cpp_macro_p (node) || (node->flags & NODE_CONDITIONAL);
|| ((node->flags & NODE_CONDITIONAL) != 0));
_cpp_mark_macro_used (node); _cpp_mark_macro_used (node);
if (!(node->flags & NODE_USED)) _cpp_maybe_notify_macro_use (pfile, 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);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
else
{
if (pfile->cb.used_undef)
pfile->cb.used_undef (pfile, pfile->directive_line, node);
}
}
if (pfile->cb.used) if (pfile->cb.used)
pfile->cb.used (pfile, pfile->directive_line, node); pfile->cb.used (pfile, pfile->directive_line, node);
check_eol (pfile, false); check_eol (pfile, false);
...@@ -2006,26 +1989,10 @@ do_ifndef (cpp_reader *pfile) ...@@ -2006,26 +1989,10 @@ do_ifndef (cpp_reader *pfile)
the powerpc and spu ports using conditional macros for 'vector', the powerpc and spu ports using conditional macros for 'vector',
'bool', and 'pixel' to act as conditional keywords. This messes 'bool', and 'pixel' to act as conditional keywords. This messes
up tests like #ifndef bool. */ up tests like #ifndef bool. */
skip = (node->type == NT_MACRO skip = (cpp_macro_p (node)
&& ((node->flags & NODE_CONDITIONAL) == 0)); && !(node->flags & NODE_CONDITIONAL));
_cpp_mark_macro_used (node); _cpp_mark_macro_used (node);
if (!(node->flags & NODE_USED)) _cpp_maybe_notify_macro_use (pfile, 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);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
else
{
if (pfile->cb.used_undef)
pfile->cb.used_undef (pfile, pfile->directive_line, node);
}
}
if (pfile->cb.used) if (pfile->cb.used)
pfile->cb.used (pfile, pfile->directive_line, node); pfile->cb.used (pfile, pfile->directive_line, node);
check_eol (pfile, false); check_eol (pfile, false);
...@@ -2508,18 +2475,18 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c) ...@@ -2508,18 +2475,18 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c)
if (pfile->cb.before_define) if (pfile->cb.before_define)
pfile->cb.before_define (pfile); pfile->cb.before_define (pfile);
if (node->type == NT_MACRO) if (cpp_macro_p (node))
{ {
if (pfile->cb.undef) if (pfile->cb.undef)
pfile->cb.undef (pfile, pfile->directive_line, node); pfile->cb.undef (pfile, pfile->directive_line, node);
if (CPP_OPTION (pfile, warn_unused_macros)) if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL); _cpp_warn_if_unused_macro (pfile, node, NULL);
_cpp_free_definition (node);
} }
if (node->type != NT_VOID)
_cpp_free_definition (node);
if (c->is_undef) if (c->is_undef)
return; return;
{ {
size_t namelen; size_t namelen;
const uchar *dn; const uchar *dn;
...@@ -2530,8 +2497,6 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c) ...@@ -2530,8 +2497,6 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c)
h = cpp_lookup (pfile, c->definition, namelen); h = cpp_lookup (pfile, c->definition, namelen);
dn = c->definition + namelen; dn = c->definition + namelen;
h->type = NT_VOID;
h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
nbuf = cpp_push_buffer (pfile, dn, ustrchr (dn, '\n') - dn, true); nbuf = cpp_push_buffer (pfile, dn, ustrchr (dn, '\n') - dn, true);
if (nbuf != NULL) if (nbuf != NULL)
{ {
......
...@@ -1065,23 +1065,7 @@ parse_defined (cpp_reader *pfile) ...@@ -1065,23 +1065,7 @@ parse_defined (cpp_reader *pfile)
"this use of \"defined\" may not be portable"); "this use of \"defined\" may not be portable");
_cpp_mark_macro_used (node); _cpp_mark_macro_used (node);
if (!(node->flags & NODE_USED)) _cpp_maybe_notify_macro_use (pfile, 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);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
else
{
if (pfile->cb.used_undef)
pfile->cb.used_undef (pfile, pfile->directive_line, node);
}
}
/* A possible controlling macro of the form #if !defined (). /* A possible controlling macro of the form #if !defined ().
_cpp_parse_expr checks there was no other junk on the line. */ _cpp_parse_expr checks there was no other junk on the line. */
...@@ -1097,8 +1081,8 @@ parse_defined (cpp_reader *pfile) ...@@ -1097,8 +1081,8 @@ parse_defined (cpp_reader *pfile)
result.unsignedp = false; result.unsignedp = false;
result.high = 0; result.high = 0;
result.overflow = false; result.overflow = false;
result.low = (node && node->type == NT_MACRO result.low = (node && cpp_macro_p (node)
&& (node->flags & NODE_CONDITIONAL) == 0); && !(node->flags & NODE_CONDITIONAL));
return result; return result;
} }
......
...@@ -805,7 +805,7 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import, ...@@ -805,7 +805,7 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import,
/* Skip if the file had a header guard and the macro is defined. /* Skip if the file had a header guard and the macro is defined.
PCH relies on this appearing before the PCH handler below. */ PCH relies on this appearing before the PCH handler below. */
if (file->cmacro && file->cmacro->type == NT_MACRO) if (file->cmacro && cpp_macro_p (file->cmacro))
return false; return false;
/* Handle PCH files immediately; don't stack them. */ /* Handle PCH files immediately; don't stack them. */
......
...@@ -104,8 +104,8 @@ cpp_defined (cpp_reader *pfile, const unsigned char *str, int len) ...@@ -104,8 +104,8 @@ cpp_defined (cpp_reader *pfile, const unsigned char *str, int len)
node = CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_NO_INSERT)); node = CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_NO_INSERT));
/* If it's of type NT_MACRO, it cannot be poisoned. */ /* If it's a macro, it cannot have been poisoned. */
return node && node->type == NT_MACRO; return node && cpp_macro_p (node);
} }
/* We don't need a proxy since the hash table's identifier comes first /* We don't need a proxy since the hash table's identifier comes first
......
...@@ -890,7 +890,21 @@ extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, ...@@ -890,7 +890,21 @@ extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
extern const cpp_token *cpp_get_token (cpp_reader *); extern const cpp_token *cpp_get_token (cpp_reader *);
extern const cpp_token *cpp_get_token_with_location (cpp_reader *, extern const cpp_token *cpp_get_token_with_location (cpp_reader *,
source_location *); source_location *);
extern bool cpp_fun_like_macro_p (cpp_hashnode *); inline bool cpp_user_macro_p (const cpp_hashnode *node)
{
return node->type == NT_MACRO && !(node->flags & NODE_BUILTIN);
}
inline bool cpp_builtin_macro_p (const cpp_hashnode *node)
{
return node->flags & NODE_BUILTIN;
}
inline bool cpp_macro_p (const cpp_hashnode *node)
{
return node->type == NT_MACRO;
}
/* Returns true if NODE is a function-like user macro. */
extern bool cpp_fun_like_macro_p (cpp_hashnode *node);
extern const unsigned char *cpp_macro_definition (cpp_reader *, extern const unsigned char *cpp_macro_definition (cpp_reader *,
cpp_hashnode *); cpp_hashnode *);
extern source_location cpp_macro_definition_location (cpp_hashnode *); extern source_location cpp_macro_definition_location (cpp_hashnode *);
......
...@@ -93,9 +93,8 @@ struct dummy ...@@ -93,9 +93,8 @@ struct dummy
#define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) #define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1))
#define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) #define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT)
#define _cpp_mark_macro_used(NODE) do { \ #define _cpp_mark_macro_used(NODE) \
if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \ (cpp_user_macro_p (NODE) ? (NODE)->value.macro->used = 1 : 0)
(NODE)->value.macro->used = 1; } while (0)
/* A generic memory buffer, and operations on it. */ /* A generic memory buffer, and operations on it. */
typedef struct _cpp_buff _cpp_buff; typedef struct _cpp_buff _cpp_buff;
...@@ -622,6 +621,12 @@ cpp_in_primary_file (cpp_reader *pfile) ...@@ -622,6 +621,12 @@ cpp_in_primary_file (cpp_reader *pfile)
} }
/* In macro.c */ /* In macro.c */
extern void _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node);
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 void _cpp_free_definition (cpp_hashnode *); extern void _cpp_free_definition (cpp_hashnode *);
extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *); extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *);
extern void _cpp_pop_context (cpp_reader *); extern void _cpp_pop_context (cpp_reader *);
......
...@@ -1627,7 +1627,7 @@ is_macro(cpp_reader *pfile, const uchar *base) ...@@ -1627,7 +1627,7 @@ is_macro(cpp_reader *pfile, const uchar *base)
cpp_hashnode *result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, cpp_hashnode *result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table,
base, cur - base, hash, HT_NO_INSERT)); base, cur - base, hash, HT_NO_INSERT));
return !result ? false : (result->type == NT_MACRO); return result && cpp_macro_p (result);
} }
/* Returns true if a literal suffix does not have the expected form /* Returns true if a literal suffix does not have the expected form
......
...@@ -342,7 +342,7 @@ int ...@@ -342,7 +342,7 @@ int
_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node, _cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
void *v ATTRIBUTE_UNUSED) void *v ATTRIBUTE_UNUSED)
{ {
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) if (cpp_user_macro_p (node))
{ {
cpp_macro *macro = node->value.macro; cpp_macro *macro = node->value.macro;
...@@ -1282,8 +1282,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, ...@@ -1282,8 +1282,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
pfile->cb.used_define (pfile, pfile->directive_line, node); pfile->cb.used_define (pfile, pfile->directive_line, node);
} }
/* Handle standard macros. */ if (cpp_user_macro_p (node))
if (! (node->flags & NODE_BUILTIN))
{ {
cpp_macro *macro = node->value.macro; cpp_macro *macro = node->value.macro;
_cpp_buff *pragma_buff = NULL; _cpp_buff *pragma_buff = NULL;
...@@ -1413,10 +1412,8 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, ...@@ -1413,10 +1412,8 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
source_location expand_loc; source_location expand_loc;
if (/* The top-level macro invocation that triggered the expansion if (/* The top-level macro invocation that triggered the expansion
we are looking at is with a standard macro ... */ we are looking at is with a function-like user macro ... */
!(pfile->top_most_macro_node->flags & NODE_BUILTIN) cpp_fun_like_macro_p (pfile->top_most_macro_node)
/* ... and it's a function-like macro invocation, */
&& pfile->top_most_macro_node->value.macro->fun_like
/* ... and we are tracking the macro expansion. */ /* ... and we are tracking the macro expansion. */
&& CPP_OPTION (pfile, track_macro_expansion)) && CPP_OPTION (pfile, track_macro_expansion))
/* Then the location of the end of the macro invocation is the /* Then the location of the end of the macro invocation is the
...@@ -3505,25 +3502,23 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) ...@@ -3505,25 +3502,23 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
if (warn_of_redefinition (pfile, node, macro)) if (warn_of_redefinition (pfile, node, macro))
{ {
const int reason = ((node->flags & NODE_BUILTIN) const int reason
&& !(node->flags & NODE_WARN)) = (cpp_builtin_macro_p (node) && !(node->flags & NODE_WARN))
? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE; ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;
bool warned = bool warned =
cpp_pedwarning_with_line (pfile, reason, cpp_pedwarning_with_line (pfile, reason,
pfile->directive_line, 0, pfile->directive_line, 0,
"\"%s\" redefined", NODE_NAME (node)); "\"%s\" redefined", NODE_NAME (node));
if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) if (warned && cpp_user_macro_p (node))
cpp_error_with_line (pfile, CPP_DL_NOTE, cpp_error_with_line (pfile, CPP_DL_NOTE,
node->value.macro->line, 0, node->value.macro->line, 0,
"this is the location of the previous definition"); "this is the location of the previous definition");
} }
_cpp_free_definition (node);
} }
if (node->type != NT_VOID)
_cpp_free_definition (node);
/* Enter definition in hash table. */ /* Enter definition in hash table. */
node->type = NT_MACRO; node->type = NT_MACRO;
node->value.macro = macro; node->value.macro = macro;
...@@ -3544,6 +3539,34 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) ...@@ -3544,6 +3539,34 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
return ok; return ok;
} }
/* Notify the use of NODE in a macro-aware context (i.e. expanding it,
or testing its existance). Also applies any lazy definition. */
extern void
_cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node)
{
node->flags |= NODE_USED;
switch (node->type)
{
case NT_MACRO:
if ((node->flags & NODE_BUILTIN)
&& pfile->cb.user_builtin_macro)
pfile->cb.user_builtin_macro (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
break;
case NT_VOID:
if (pfile->cb.used_undef)
pfile->cb.used_undef (pfile, pfile->directive_line, node);
break;
default:
abort ();
}
}
/* Warn if a token in STRING matches one of a function-like MACRO's /* Warn if a token in STRING matches one of a function-like MACRO's
parameters. */ parameters. */
static void static void
......
...@@ -325,7 +325,7 @@ _cpp_read_logical_line_trad (cpp_reader *pfile) ...@@ -325,7 +325,7 @@ _cpp_read_logical_line_trad (cpp_reader *pfile)
static inline bool static inline bool
fun_like_macro (cpp_hashnode *node) fun_like_macro (cpp_hashnode *node)
{ {
if (node->flags & NODE_BUILTIN) if (cpp_builtin_macro_p (node))
return node->value.builtin == BT_HAS_ATTRIBUTE; return node->value.builtin == BT_HAS_ATTRIBUTE;
else else
return node->value.macro->fun_like; return node->value.macro->fun_like;
...@@ -338,7 +338,7 @@ maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start, ...@@ -338,7 +338,7 @@ maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start,
struct fun_macro *macro) struct fun_macro *macro)
{ {
unsigned int n; unsigned int n;
if (node->flags & NODE_BUILTIN) if (cpp_builtin_macro_p (node))
n = 1; n = 1;
else else
n = node->value.macro->paramc; n = node->value.macro->paramc;
...@@ -521,7 +521,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro, ...@@ -521,7 +521,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro,
out = pfile->out.cur; out = pfile->out.cur;
cur = CUR (context); cur = CUR (context);
if (node->type == NT_MACRO if (cpp_macro_p (node)
/* Should we expand for ls_answer? */ /* Should we expand for ls_answer? */
&& (lex_state == ls_none || lex_state == ls_fun_open) && (lex_state == ls_none || lex_state == ls_fun_open)
&& !pfile->state.prevent_expansion) && !pfile->state.prevent_expansion)
...@@ -610,7 +610,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro, ...@@ -610,7 +610,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro,
paren_depth--; paren_depth--;
if (lex_state == ls_fun_close && paren_depth == 0) if (lex_state == ls_fun_close && paren_depth == 0)
{ {
if (fmacro.node->flags & NODE_BUILTIN) if (cpp_builtin_macro_p (fmacro.node))
{ {
/* Handle builtin function-like macros like /* Handle builtin function-like macros like
__has_attribute. The already parsed arguments __has_attribute. The already parsed arguments
...@@ -839,7 +839,7 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node) ...@@ -839,7 +839,7 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
const uchar *text; const uchar *text;
uchar *buf; uchar *buf;
if (node->flags & NODE_BUILTIN) if (cpp_builtin_macro_p (node))
{ {
text = _cpp_builtin_macro_text (pfile, node); text = _cpp_builtin_macro_text (pfile, node);
len = ustrlen (text); len = ustrlen (text);
......
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