From 3f6677f418564e634e3b77b0fc385891d1fdf1da Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 16 Aug 2018 13:51:38 +0000 Subject: [PATCH] [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 --- gcc/ChangeLog | 5 +++ gcc/c-family/ChangeLog | 7 ++++ gcc/c-family/c-ada-spec.c | 29 +++++++-------- gcc/c-family/c-ppoutput.c | 17 ++++----- gcc/c-family/c-spellcheck.cc | 10 +++--- gcc/config/powerpcspe/powerpcspe-c.c | 9 ++--- gcc/config/rs6000/rs6000-c.c | 10 +++--- gcc/cp/name-lookup.c | 8 ++--- gcc/fortran/ChangeLog | 4 +++ gcc/fortran/cpp.c | 2 +- libcpp/ChangeLog | 26 ++++++++++++++ libcpp/directives.c | 53 +++++----------------------- libcpp/expr.c | 22 ++---------- libcpp/files.c | 2 +- libcpp/identifiers.c | 4 +-- libcpp/include/cpplib.h | 16 ++++++++- libcpp/internal.h | 11 ++++-- libcpp/lex.c | 2 +- libcpp/macro.c | 51 ++++++++++++++++++-------- libcpp/traditional.c | 10 +++--- 20 files changed, 166 insertions(+), 132 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aaed5d54a4b..fdac7e758c9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-08-16 Nathan Sidwell + + * 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 PR target/84711 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index b94a7ae9ab7..d293d990b17 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2018-08-16 Nathan Sidwell + + * 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 * c-format.c: Include "selftest-diagnostic.h" and diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c index 9c7de23a04e..c6447ab01c9 100644 --- a/gcc/c-family/c-ada-spec.c +++ b/gcc/c-family/c-ada-spec.c @@ -171,13 +171,12 @@ static int count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) { - const cpp_macro *macro = node->value.macro; - - if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN) - && macro->count - && *NODE_NAME (node) != '_' - && LOCATION_FILE (macro->line) == macro_source_file) - max_ada_macros++; + if (cpp_user_macro_p (node) && *NODE_NAME (node) != '_') + { + const cpp_macro *macro = node->value.macro; + if (macro->count && LOCATION_FILE (macro->line) == macro_source_file) + max_ada_macros++; + } return 1; } @@ -190,15 +189,13 @@ static int store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node, void *macros) { - const cpp_macro *macro = node->value.macro; - - if (node->type == NT_MACRO - && !(node->flags & NODE_BUILTIN) - && macro->count - && *NODE_NAME (node) != '_' - && LOCATION_FILE (macro->line) == macro_source_file) - ((cpp_hashnode **) macros)[store_ada_macro_index++] = node; - + if (cpp_user_macro_p (node) && *NODE_NAME (node) != '_') + { + const cpp_macro *macro = node->value.macro; + if (macro->count + && LOCATION_FILE (macro->line) == macro_source_file) + ((cpp_hashnode **) macros)[store_ada_macro_index++] = node; + } return 1; } diff --git a/gcc/c-family/c-ppoutput.c b/gcc/c-family/c-ppoutput.c index b8fc1c6dad9..2e5a44ed727 100644 --- a/gcc/c-family/c-ppoutput.c +++ b/gcc/c-family/c-ppoutput.c @@ -532,13 +532,14 @@ static void cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED, cpp_hashnode *node) { - macro_queue *q; - if (node->flags & NODE_BUILTIN) - return; - q = XNEW (macro_queue); - q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node)); - q->next = define_queue; - define_queue = q; + if (cpp_user_macro_p (node)) + { + macro_queue *q; + q = XNEW (macro_queue); + q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node)); + q->next = define_queue; + define_queue = q; + } } static void @@ -688,7 +689,7 @@ cb_def_pragma (cpp_reader *pfile, source_location line) static int 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 ((const char *) cpp_macro_definition (pfile, node), diff --git a/gcc/c-family/c-spellcheck.cc b/gcc/c-family/c-spellcheck.cc index c0975d32ea4..85fd278f4ac 100644 --- a/gcc/c-family/c-spellcheck.cc +++ b/gcc/c-family/c-spellcheck.cc @@ -45,13 +45,13 @@ name_reserved_for_implementation_p (const char *str) static bool should_suggest_as_macro_p (cpp_hashnode *hashnode) { - if (hashnode->type != NT_MACRO) + if (!cpp_macro_p (hashnode)) return false; - /* Don't suggest names reserved for the implementation, but do suggest the builtin - macros such as __FILE__, __LINE__ etc. */ - if (name_reserved_for_implementation_p ((const char *)hashnode->ident.str) - && !(hashnode->flags & NODE_BUILTIN)) + /* Don't suggest names reserved for the implementation, but do + suggest the builtin macros such as __FILE__, __LINE__ etc. */ + if (cpp_user_macro_p (hashnode) + && name_reserved_for_implementation_p ((const char *)hashnode->ident.str)) return false; return true; diff --git a/gcc/config/powerpcspe/powerpcspe-c.c b/gcc/config/powerpcspe/powerpcspe-c.c index 157c1853aa4..0e69ebb994f 100644 --- a/gcc/config/powerpcspe/powerpcspe-c.c +++ b/gcc/config/powerpcspe/powerpcspe-c.c @@ -220,21 +220,22 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword))) { 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 invoked with or without arguments. Without following ( treat it like non-macro, otherwise the following cpp_get_token eats 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; do tok = cpp_peek_token (pfile, idx2++); while (tok->type == CPP_PADDING); if (tok->type != CPP_OPEN_PAREN) - itype = NT_VOID; + is_macro = false; } - if (itype == NT_MACRO) + if (is_macro) { do (void) cpp_get_token (pfile); diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index f37f0b1503d..4d5e3c226ab 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -220,21 +220,23 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword))) { 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 invoked with or without arguments. Without following ( treat it like non-macro, otherwise the following cpp_get_token eats 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; do tok = cpp_peek_token (pfile, idx2++); while (tok->type == CPP_PADDING); if (tok->type != CPP_OPEN_PAREN) - itype = NT_VOID; + is_macro = false; } - if (itype == NT_MACRO) + + if (is_macro) { do (void) cpp_get_token (pfile); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 0faf739cd6a..3ba76447f98 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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 macro was used with the wrong argument count, or the macro has been used before it was defined. */ - cpp_hashnode *macro = bmm.blithely_get_best_candidate (); - if (macro && (macro->flags & NODE_BUILTIN) == 0) - return name_hint (NULL, - macro_use_before_def::maybe_make (loc, macro)); + if (cpp_hashnode *macro = bmm.blithely_get_best_candidate ()) + if (cpp_user_macro_p (macro)) + return name_hint (NULL, + macro_use_before_def::maybe_make (loc, macro)); } /* Try the "starts_decl_specifier_p" keywords to detect diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e4403523301..dc4aa1acf74 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,7 @@ +2018-08-16 Nathan Sidwell + + * cpp.c (dump_macro): Use cpp_user_macro_p. + 2018-08-14 Janus Weil PR fortran/86116 diff --git a/gcc/fortran/cpp.c b/gcc/fortran/cpp.c index 4320461d07c..0b3de42e832 100644 --- a/gcc/fortran/cpp.c +++ b/gcc/fortran/cpp.c @@ -990,7 +990,7 @@ cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, static int 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 ((const char *) cpp_macro_definition (pfile, node), diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index a39144c6b01..2bab8a72b59 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,29 @@ +2018-08-16 Nathan Sidwell + + 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 * include/line-map.h (struct location_range): Add "m_label" field. diff --git a/libcpp/directives.c b/libcpp/directives.c index 352c59150d7..6ddfce6778f 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -1666,7 +1666,7 @@ do_pragma_poison (cpp_reader *pfile) if (hp->flags & NODE_POISONED) continue; - if (hp->type == NT_MACRO) + if (cpp_macro_p (hp)) cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"", NODE_NAME (hp)); _cpp_free_definition (hp); @@ -1960,26 +1960,9 @@ do_ifdef (cpp_reader *pfile) the powerpc and spu ports using conditional macros for 'vector', 'bool', and 'pixel' to act as conditional keywords. This messes up tests like #ifndef bool. */ - skip = (node->type != NT_MACRO - || ((node->flags & NODE_CONDITIONAL) != 0)); + skip = !cpp_macro_p (node) || (node->flags & NODE_CONDITIONAL); _cpp_mark_macro_used (node); - if (!(node->flags & NODE_USED)) - { - 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); - } - } + _cpp_maybe_notify_macro_use (pfile, node); if (pfile->cb.used) pfile->cb.used (pfile, pfile->directive_line, node); check_eol (pfile, false); @@ -2006,26 +1989,10 @@ do_ifndef (cpp_reader *pfile) the powerpc and spu ports using conditional macros for 'vector', 'bool', and 'pixel' to act as conditional keywords. This messes up tests like #ifndef bool. */ - skip = (node->type == NT_MACRO - && ((node->flags & NODE_CONDITIONAL) == 0)); + skip = (cpp_macro_p (node) + && !(node->flags & NODE_CONDITIONAL)); _cpp_mark_macro_used (node); - if (!(node->flags & NODE_USED)) - { - 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); - } - } + _cpp_maybe_notify_macro_use (pfile, node); if (pfile->cb.used) pfile->cb.used (pfile, pfile->directive_line, node); check_eol (pfile, false); @@ -2508,18 +2475,18 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c) if (pfile->cb.before_define) pfile->cb.before_define (pfile); - if (node->type == NT_MACRO) + if (cpp_macro_p (node)) { if (pfile->cb.undef) pfile->cb.undef (pfile, pfile->directive_line, node); if (CPP_OPTION (pfile, warn_unused_macros)) _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) return; + { size_t namelen; const uchar *dn; @@ -2530,8 +2497,6 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c) h = cpp_lookup (pfile, 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); if (nbuf != NULL) { diff --git a/libcpp/expr.c b/libcpp/expr.c index 36c3fc474d6..201a6197bcd 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -1065,23 +1065,7 @@ parse_defined (cpp_reader *pfile) "this use of \"defined\" may not be portable"); _cpp_mark_macro_used (node); - if (!(node->flags & NODE_USED)) - { - 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); - } - } + _cpp_maybe_notify_macro_use (pfile, node); /* A possible controlling macro of the form #if !defined (). _cpp_parse_expr checks there was no other junk on the line. */ @@ -1097,8 +1081,8 @@ parse_defined (cpp_reader *pfile) result.unsignedp = false; result.high = 0; result.overflow = false; - result.low = (node && node->type == NT_MACRO - && (node->flags & NODE_CONDITIONAL) == 0); + result.low = (node && cpp_macro_p (node) + && !(node->flags & NODE_CONDITIONAL)); return result; } diff --git a/libcpp/files.c b/libcpp/files.c index e8d21b28e62..08b7c647c91 100644 --- a/libcpp/files.c +++ b/libcpp/files.c @@ -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. 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; /* Handle PCH files immediately; don't stack them. */ diff --git a/libcpp/identifiers.c b/libcpp/identifiers.c index 16584a6ab8a..3d42d1a6b8d 100644 --- a/libcpp/identifiers.c +++ b/libcpp/identifiers.c @@ -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)); - /* If it's of type NT_MACRO, it cannot be poisoned. */ - return node && node->type == NT_MACRO; + /* If it's a macro, it cannot have been poisoned. */ + return node && cpp_macro_p (node); } /* We don't need a proxy since the hash table's identifier comes first diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 3ad52d5e01e..99992a280ba 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -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_with_location (cpp_reader *, 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 *, cpp_hashnode *); extern source_location cpp_macro_definition_location (cpp_hashnode *); diff --git a/libcpp/internal.h b/libcpp/internal.h index 782d8e6349f..dd145ab57c6 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -93,9 +93,8 @@ struct dummy #define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) #define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) -#define _cpp_mark_macro_used(NODE) do { \ - if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \ - (NODE)->value.macro->used = 1; } while (0) +#define _cpp_mark_macro_used(NODE) \ + (cpp_user_macro_p (NODE) ? (NODE)->value.macro->used = 1 : 0) /* A generic memory buffer, and operations on it. */ typedef struct _cpp_buff _cpp_buff; @@ -622,6 +621,12 @@ cpp_in_primary_file (cpp_reader *pfile) } /* 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 bool _cpp_create_definition (cpp_reader *, cpp_hashnode *); extern void _cpp_pop_context (cpp_reader *); diff --git a/libcpp/lex.c b/libcpp/lex.c index a2592e045d2..fa465beadb0 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -1627,7 +1627,7 @@ is_macro(cpp_reader *pfile, const uchar *base) cpp_hashnode *result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, 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 diff --git a/libcpp/macro.c b/libcpp/macro.c index 683f918145c..5d4cd7838ff 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -342,7 +342,7 @@ int _cpp_warn_if_unused_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)) { cpp_macro *macro = node->value.macro; @@ -1282,8 +1282,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, pfile->cb.used_define (pfile, pfile->directive_line, node); } - /* Handle standard macros. */ - if (! (node->flags & NODE_BUILTIN)) + if (cpp_user_macro_p (node)) { cpp_macro *macro = node->value.macro; _cpp_buff *pragma_buff = NULL; @@ -1413,10 +1412,8 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, source_location expand_loc; if (/* The top-level macro invocation that triggered the expansion - we are looking at is with a standard macro ... */ - !(pfile->top_most_macro_node->flags & NODE_BUILTIN) - /* ... and it's a function-like macro invocation, */ - && pfile->top_most_macro_node->value.macro->fun_like + we are looking at is with a function-like user macro ... */ + cpp_fun_like_macro_p (pfile->top_most_macro_node) /* ... and we are tracking the macro expansion. */ && CPP_OPTION (pfile, track_macro_expansion)) /* 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) if (warn_of_redefinition (pfile, node, macro)) { - const int reason = ((node->flags & NODE_BUILTIN) - && !(node->flags & NODE_WARN)) - ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE; + const int reason + = (cpp_builtin_macro_p (node) && !(node->flags & NODE_WARN)) + ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE; bool warned = cpp_pedwarning_with_line (pfile, reason, pfile->directive_line, 0, "\"%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, node->value.macro->line, 0, "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. */ node->type = NT_MACRO; node->value.macro = macro; @@ -3544,6 +3539,34 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) 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 parameters. */ static void diff --git a/libcpp/traditional.c b/libcpp/traditional.c index b25d5222d8a..aa38ea4426d 100644 --- a/libcpp/traditional.c +++ b/libcpp/traditional.c @@ -325,7 +325,7 @@ _cpp_read_logical_line_trad (cpp_reader *pfile) static inline bool fun_like_macro (cpp_hashnode *node) { - if (node->flags & NODE_BUILTIN) + if (cpp_builtin_macro_p (node)) return node->value.builtin == BT_HAS_ATTRIBUTE; else return node->value.macro->fun_like; @@ -338,7 +338,7 @@ maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start, struct fun_macro *macro) { unsigned int n; - if (node->flags & NODE_BUILTIN) + if (cpp_builtin_macro_p (node)) n = 1; else n = node->value.macro->paramc; @@ -521,7 +521,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro, out = pfile->out.cur; cur = CUR (context); - if (node->type == NT_MACRO + if (cpp_macro_p (node) /* Should we expand for ls_answer? */ && (lex_state == ls_none || lex_state == ls_fun_open) && !pfile->state.prevent_expansion) @@ -610,7 +610,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro, paren_depth--; 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 __has_attribute. The already parsed arguments @@ -839,7 +839,7 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node) const uchar *text; uchar *buf; - if (node->flags & NODE_BUILTIN) + if (cpp_builtin_macro_p (node)) { text = _cpp_builtin_macro_text (pfile, node); len = ustrlen (text);