aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2018-08-16 13:51:38 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2018-08-16 13:51:38 +0000
commit3f6677f418564e634e3b77b0fc385891d1fdf1da (patch)
treefee267b2fd8d26f1c657aea624e05d02e0f67a17 /libcpp
parentba9d634f417a95d7efb875408573872c883f710a (diff)
downloadgcc-3f6677f418564e634e3b77b0fc385891d1fdf1da.zip
gcc-3f6677f418564e634e3b77b0fc385891d1fdf1da.tar.gz
gcc-3f6677f418564e634e3b77b0fc385891d1fdf1da.tar.bz2
[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
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog26
-rw-r--r--libcpp/directives.c53
-rw-r--r--libcpp/expr.c22
-rw-r--r--libcpp/files.c2
-rw-r--r--libcpp/identifiers.c4
-rw-r--r--libcpp/include/cpplib.h16
-rw-r--r--libcpp/internal.h11
-rw-r--r--libcpp/lex.c2
-rw-r--r--libcpp/macro.c51
-rw-r--r--libcpp/traditional.c10
10 files changed, 107 insertions, 90 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index a39144c..2bab8a7 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -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.
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 352c591..6ddfce6 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 36c3fc4..201a619 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 e8d21b2..08b7c64 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 16584a6..3d42d1a 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 3ad52d5..99992a2 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 782d8e6..dd145ab 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 a2592e0..fa465be 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 683f918..5d4cd78 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 b25d522..aa38ea4 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);