+2018-08-08 Nathan Sidwell <nathan@acm.org>
+
+ Move NODE_BUILTIN to NT_BUILTIN.
+ gcc/c-family/
+ * c-ppoutput.c (cb_used_define): Use cpp_macro_p.
+ gcc/cp/
+ * name-lookup.c (lookup_name_fuzzy): Use cpp_macro_p.
+ libcpp/
+ * directives.c (do_undef): Adjust macro detection.
+ (undefine_macros): Adjust.
+ (do_pragma_poison, do_ifndef, do_ifdef, cpp_pop_definition):
+ Adjust.
+ * expr.c (parse_defined): Adjust.
+ * files.c (should_stack_file): Adjust.
+ * identifiers.c (cpp_defined): Adjust.
+ * include/cpplib.h (NODE_BUILTIN): Delete.
+ (enum node_type): Add NT_BUILTIN.
+ (CPP_HASHNODE_VALUE_IDX): Adjust.
+ * init.c (cpp_init_special_builtins): Adjust.
+ * internal.h (_cpp_mark_macro, _cpp_maybe_lazy_macro): Adjust.
+ * lex.c (is_macro): Adjust.
+ * macro.c (struct macro_arg_saved_data): Add type field.
+ (_cpp_warn_if_unused_macro): Adjust.
+ (enter_macro_context, cpp_get_token_1, warn_of_redefinition)
+ (_cpp_free_defintion, _cpp_safe_parameter)
+ (_cpp_unsave_parameters, _cpp_create_definition): Adjust.
+ (cpp_macro_p): Adjust.
+ * pch.c (write_macdef, count_defs, write_defs, cpp_validate_state)
+ (save_macros): Adjust.
+ * traditional.c (fun_like_macro, maybe_start_funlike)
+ (_cpp_scan_out_logical_line, push_replacement_text): Adjust.
+
2018-08-07 Nathan Sidwell <nathan@acm.org>
Move NODE_MACRO_ARG to NT_MACRO_ARG.
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_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
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)
+ if (macro && cpp_macro_p (macro))
return name_hint (NULL,
macro_use_before_def::maybe_make (loc, macro));
}
/* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified
identifier is not currently defined as a macro name. */
- if (node->type == NT_MACRO)
+ if (node->type & NT_MACRO)
{
if (node->flags & NODE_WARN)
cpp_error (pfile, CPP_DL_WARNING,
"undefining \"%s\"", NODE_NAME (node));
- else if ((node->flags & NODE_BUILTIN)
+ else if ((node->type == NT_BUILTIN)
&& CPP_OPTION (pfile, warn_builtin_macro_redefined))
cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED,
pfile->directive_line, 0,
/* Body of _cpp_free_definition inlined here for speed.
Macros and assertions no longer have anything to free. */
h->type = NT_VOID;
- h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
+ h->flags &= ~(NODE_POISONED|NODE_DISABLED|NODE_USED);
+ h->value.macro = NULL;
return 1;
}
if (hp->flags & NODE_POISONED)
continue;
- if (hp->type == NT_MACRO)
+ if (hp->type & NT_MACRO)
cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"",
NODE_NAME (hp));
_cpp_free_definition (hp);
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
+ skip = (node->type == NT_VOID
|| ((node->flags & NODE_CONDITIONAL) != 0));
_cpp_mark_macro_used (node);
if (!(node->flags & NODE_USED))
{
node->flags |= NODE_USED;
- if (node->type == NT_MACRO)
+ if (node->type & NT_MACRO)
{
- _cpp_maybe_lazy_macro (pfile, node);
+ if (node->type == NT_MACRO)
+ _cpp_maybe_lazy_macro (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
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
+ skip = (node->type != NT_VOID
&& ((node->flags & NODE_CONDITIONAL) == 0));
_cpp_mark_macro_used (node);
if (!(node->flags & NODE_USED))
{
node->flags |= NODE_USED;
- if (node->type == NT_MACRO)
+ if (node->type & NT_MACRO)
{
- _cpp_maybe_lazy_macro (pfile, node);
+ if (node->type == NT_MACRO)
+ _cpp_maybe_lazy_macro (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
if (pfile->cb.before_define)
pfile->cb.before_define (pfile);
- if (node->type == NT_MACRO)
+ if (node->type & NT_MACRO)
{
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);
}
+
if (node->type != NT_VOID)
_cpp_free_definition (node);
if (c->is_undef)
return;
+
{
size_t namelen;
const uchar *dn;
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)
{
if (!(node->flags & NODE_USED))
{
node->flags |= NODE_USED;
- if (node->type == NT_MACRO)
+ if (node->type & NT_MACRO)
{
- _cpp_maybe_lazy_macro (pfile, node);
+ if (node->type == NT_MACRO)
+ _cpp_maybe_lazy_macro (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
result.unsignedp = false;
result.high = 0;
result.overflow = false;
- result.low = (node && node->type == NT_MACRO
+ result.low = (node && node->type & NT_MACRO
&& (node->flags & NODE_CONDITIONAL) == 0);
return result;
}
/* 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 && file->cmacro->type & NT_MACRO)
return false;
/* Handle PCH files immediately; don't stack them. */
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 be poisoned. */
+ return node && node->type & NT_MACRO;
}
/* We don't need a proxy since the hash table's identifier comes first
/* Hash node flags. */
#define NODE_OPERATOR (1 << 0) /* C++ named operator. */
#define NODE_POISONED (1 << 1) /* Poisoned identifier. */
-#define NODE_BUILTIN (1 << 2) /* Builtin macro. */
+
#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */
#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */
#define NODE_DISABLED (1 << 5) /* A disabled macro. */
-//#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */
+
#define NODE_USED (1 << 7) /* Dumped with -dU. */
#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */
#define NODE_WARN_OPERATOR (1 << 9) /* Warn about C++ named operator. */
{
NT_VOID = 0, /* No definition yet. */
NT_MACRO_ARG, /* A macro arg. */
- NT_MACRO, /* A macro or assert. */
- NT_BUILTIN, /* A builtin macro. */
+ NT_MACRO, /* A user macro or assert. */
+ NT_BUILTIN /* A builtin macro. */
};
/* Different flavors of builtin macro. _Pragma is an operator, but we
#define CPP_HASHNODE_VALUE_IDX(HNODE) \
((HNODE).type == NT_MACRO_ARG ? NTV_ARGUMENT \
- : (HNODE).flags & NODE_BUILTIN ? NTV_BUILTIN \
+ : (HNODE).type == NT_BUILTIN ? NTV_BUILTIN \
: NTV_MACRO)
/* The common part of an identifier node shared amongst all 3 C front
|| pfile->cb.has_attribute == NULL))
continue;
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
- hp->type = NT_MACRO;
- hp->flags |= NODE_BUILTIN;
+ hp->type = NT_BUILTIN;
if (b->always_warn_if_redefined)
hp->flags |= NODE_WARN;
hp->value.builtin = (enum cpp_builtin_type) b->value;
#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)) \
+ if ((NODE)->type == NT_MACRO) \
(NODE)->value.macro->used = 1; } while (0)
/* A generic memory buffer, and operations on it. */
extern cpp_macro *_cpp_do_lazy_macro (cpp_reader *pfile, cpp_macro *macro);
inline cpp_macro *_cpp_maybe_lazy_macro (cpp_reader *pfile, cpp_hashnode *node)
{
- cpp_macro *macro = (node->flags & NODE_BUILTIN) ? NULL : node->value.macro;
- if (macro && macro->lazy)
+ cpp_macro *macro = node->value.macro;
+ if (macro->lazy)
macro = _cpp_do_lazy_macro (pfile, macro);
return macro;
}
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 ? result->type & NT_MACRO : false;
}
/* Returns true if a literal suffix does not have the expected form
struct macro_arg_saved_data {
/* The canonical (UTF-8) spelling of this identifier. */
cpp_hashnode *canonical_node;
- /* The previous value of this identifier. */
+ /* The previous value & type of this identifier. */
union _cpp_hashnode_value value;
+ node_type type;
};
static const char *vaopt_paste_error =
_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 (node->type == NT_MACRO)
{
cpp_macro *macro = node->value.macro;
function where set this flag to FALSE. */
pfile->about_to_expand_macro_p = true;
- if (!(node->flags & NODE_BUILTIN))
+ if (node->type == NT_MACRO)
{
cpp_macro *macro = _cpp_maybe_lazy_macro (pfile, node);
_cpp_buff *pragma_buff = NULL;
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)
+ pfile->top_most_macro_node->type == NT_MACRO
/* ... and it's a function-like macro invocation, */
&& pfile->top_most_macro_node->value.macro->fun_like
/* ... and we are tracking the macro expansion. */
node = result->val.node.node;
- if (node->type != NT_MACRO || (result->flags & NO_EXPAND))
+ if (node->type == NT_VOID || (result->flags & NO_EXPAND))
break;
if (!(node->flags & NODE_DISABLED))
/* Suppress warnings for builtins that lack the NODE_WARN flag,
unless Wbuiltin-macro-redefined. */
- if (node->flags & NODE_BUILTIN)
+ if (node->type == NT_BUILTIN)
return CPP_OPTION (pfile, warn_builtin_macro_redefined);
/* Redefinitions of conditional (context-sensitive) macros, on
{
/* Macros and assertions no longer have anything to free. */
h->type = NT_VOID;
- /* Clear builtin flag in case of redefinition. */
- h->flags &= ~(NODE_BUILTIN | NODE_DISABLED | NODE_USED);
+ h->flags &= ~(NODE_DISABLED | NODE_USED);
h->value.macro = NULL;
}
}
macro_arg_saved_data *saved = (macro_arg_saved_data *)pfile->macro_buffer;
- saved[n].value = node->value;
saved[n].canonical_node = node;
+ saved[n].value = node->value;
+ saved[n].type = node->type;
void *base = _cpp_reserve_room (pfile, n * sizeof (cpp_hashnode *),
sizeof (cpp_hashnode *));
&((struct macro_arg_saved_data *) pfile->macro_buffer)[n];
struct cpp_hashnode *node = save->canonical_node;
+ node->type = save->type;
node->value = save->value;
- node->type = (node->flags & NODE_BUILTIN || node->value.macro
- ? NT_MACRO : NT_VOID);
}
}
if (!macro)
return false;
- if (node->type == NT_MACRO)
+ if (node->type & NT_MACRO)
{
if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL);
if (warn_of_redefinition (pfile, node, macro))
{
- const int reason = ((node->flags & NODE_BUILTIN)
+ const int reason = ((node->type == NT_BUILTIN)
&& !(node->flags & NODE_WARN))
? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;
pfile->directive_line, 0,
"\"%s\" redefined", NODE_NAME (node));
- if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
+ if (warned && node->type == NT_MACRO)
cpp_error_with_line (pfile, CPP_DL_NOTE,
node->value.macro->line, 0,
"this is the location of the previous definition");
bool
cpp_macro_p (cpp_hashnode *node, bool builtin_ok)
{
- if (node->type != NT_MACRO)
- return false;
- if (node->flags & NODE_BUILTIN)
+ if (node->type == NT_BUILTIN)
return builtin_ok;
- return node->value.macro->kind != cmk_assert;
+
+ if (node->type == NT_MACRO)
+ return node->value.macro->kind != cmk_assert;
+
+ return false;
}
/* Returns true if NODE is a function-like macro. */
is_void = true;
goto poisoned;
+ case NT_BUILTIN:
+ return 1;
+
case NT_MACRO:
- if (!(hn->flags & NODE_BUILTIN)
- && hn->value.macro->kind != cmk_assert)
+ if (hn->value.macro->kind != cmk_assert)
{
poisoned:
struct macrodef_struct s;
switch (hn->type)
{
+ case NT_BUILTIN:
+ return 1;
+
case NT_MACRO:
- if (hn->flags & NODE_BUILTIN)
- return 1;
if (hn->value.macro->kind == cmk_assert)
return 1;
switch (hn->type)
{
+ case NT_BUILTIN:
+ return 1;
+
case NT_MACRO:
- if (hn->flags & NODE_BUILTIN)
- return 1;
if (hn->value.macro->kind == cmk_assert)
return 1;
goto fail;
}
- if (h->type != NT_MACRO)
+ if (h->type == NT_VOID)
{
/* It's ok if __GCC_HAVE_DWARF2_CFI_ASM becomes undefined,
as in, when the PCH file is created with -g and we're
struct save_macro_data *data = (struct save_macro_data *)data_p;
if (h->type == NT_MACRO
- && !(h->flags & NODE_BUILTIN)
&& h->value.macro->kind != cmk_assert)
{
if (data->count == data->array_size)
static inline bool
fun_like_macro (cpp_hashnode *node)
{
- if (node->flags & NODE_BUILTIN)
+ if (node->type == NT_BUILTIN)
return node->value.builtin == BT_HAS_ATTRIBUTE;
else
return node->value.macro->fun_like;
struct fun_macro *macro)
{
unsigned int n;
- if (node->flags & NODE_BUILTIN)
+ if (node->type == NT_BUILTIN)
n = 1;
else
n = node->value.macro->paramc;
out = pfile->out.cur;
cur = CUR (context);
- if (node->type == NT_MACRO
+ if (node->type & NT_MACRO
/* Should we expand for ls_answer? */
&& (lex_state == ls_none || lex_state == ls_fun_open)
&& !pfile->state.prevent_expansion)
paren_depth--;
if (lex_state == ls_fun_close && paren_depth == 0)
{
- if (fmacro.node->flags & NODE_BUILTIN)
+ if (fmacro.node->type == NT_BUILTIN)
{
/* Handle builtin function-like macros like
__has_attribute. The already parsed arguments
const uchar *text;
uchar *buf;
- if (node->flags & NODE_BUILTIN)
+ if (node->type == NT_BUILTIN)
{
text = _cpp_builtin_macro_text (pfile, node);
len = ustrlen (text);