[PATCH] CPP Macro predicates
authorNathan Sidwell <nathan@acm.org>
Thu, 16 Aug 2018 13:51:38 +0000 (13:51 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 16 Aug 2018 13:51:38 +0000 (13:51 +0000)
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

20 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-ada-spec.c
gcc/c-family/c-ppoutput.c
gcc/c-family/c-spellcheck.cc
gcc/config/powerpcspe/powerpcspe-c.c
gcc/config/rs6000/rs6000-c.c
gcc/cp/name-lookup.c
gcc/fortran/ChangeLog
gcc/fortran/cpp.c
libcpp/ChangeLog
libcpp/directives.c
libcpp/expr.c
libcpp/files.c
libcpp/identifiers.c
libcpp/include/cpplib.h
libcpp/internal.h
libcpp/lex.c
libcpp/macro.c
libcpp/traditional.c

index aaed5d54a4b81f1cb6220f6e42b95493c2029c37..fdac7e758c9b3d528c09bace397d620a0c121d29 100644 (file)
@@ -1,3 +1,8 @@
+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>
 
        PR target/84711
index b94a7ae9ab7ceb37100cd1111a1d645570aa746d..d293d990b17ebd130346e63a7927f2083dc7fa01 100644 (file)
@@ -1,3 +1,10 @@
+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>
 
        * c-format.c: Include "selftest-diagnostic.h" and
index 9c7de23a04ec8b41d9fbbd84a50ceb8dda898b39..c6447ab01c991e6e0ca09366a79a3d320d638764 100644 (file)
@@ -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;
 }
 
index b8fc1c6dad931c1f53dee78082a3034a0e241085..2e5a44ed72731f10bcf3ca44388bd65a869e1bfa 100644 (file)
@@ -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),
index c0975d32ea490116fe78790849c193a62b796d5f..85fd278f4ac9ac92c93013fdd239856b0abf0c45 100644 (file)
@@ -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;
index 157c1853aa45964447c290ade2625a171d6d17de..0e69ebb994f11757a3a86696e0be1d2b166b826b 100644 (file)
@@ -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);
index f37f0b1503d3f0e7e5fa72626d45a629400c8331..4d5e3c226abb39ce3ef823bcf0adad4c6869688c 100644 (file)
@@ -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);
index 0faf739cd6a88ea2210dce371b08b36e46c54611..3ba76447f98cacbd2c2477a7260861ebffefffcb 100644 (file)
@@ -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
index e44035233019133872ee25209ae07b38c7afa05b..dc4aa1acf745017223d8516d045361702d4cccd0 100644 (file)
@@ -1,3 +1,7 @@
+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>
 
        PR fortran/86116
index 4320461d07c940fcacd7b9c05336f3d057aac721..0b3de42e8325244860bae2cc85d74607cd0fe141 100644 (file)
@@ -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),
index a39144c6b014bd5ea609566431a4437d9c0c4aea..2bab8a72b595f17e40fc6b9df8de43638901cf41 100644 (file)
@@ -1,3 +1,29 @@
+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>
 
        * include/line-map.h (struct location_range): Add "m_label" field.
index 352c59150d7bcb4e4d6c83b7487efce96ac6fbb0..6ddfce6778f45d3995ad66ce353f35cdc0c4ee2a 100644 (file)
@@ -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)
       {
index 36c3fc474d669adebaa89a8c4fe35bed1e3a78e6..201a6197bcd3a7ef08b0d9b1fa4873a7fb31a719 100644 (file)
@@ -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;
 }
 
index e8d21b28e6278283d3915ddabafeb436a74b6f61..08b7c647c91406bfac0bf3d8ba55e8ada65be6f7 100644 (file)
@@ -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.  */
index 16584a6ab8ab8b08dce7a5342c0fb3b3dec12a8a..3d42d1a6b8d0a63d9baf289d08b118fea2294be6 100644 (file)
@@ -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
index 3ad52d5e01e5a78a551c937d2cc6dce4c37a0608..99992a280ba64ee28cb919175eafaa2a9967207a 100644 (file)
@@ -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 *);
index 782d8e6349f90a890dba97c6e9431b81aff3c50f..dd145ab57c67a3c89d20da1723685015da8fe637 100644 (file)
@@ -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 *);
index a2592e045d28001c31a31a5d54cc2945ab6456dd..fa465beadb025e58492bbf9947f4cf8411fceb95 100644 (file)
@@ -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
index 683f918145cd357d937b1c104bb3dcdbb1d560c9..5d4cd7838ff5afb99e8dfe124621a6a478211710 100644 (file)
@@ -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
index b25d5222d8a879cbeeb4982d01c907dca388be13..aa38ea4426d7fb8d8b661f32e6edffdddeef9a1b 100644 (file)
@@ -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);