2018-08-08 Nathan Sidwell <nathan@acm.org>
+ libcpp/
+ * include/cpplib.h (enum node_type): Rename to NT_USER_MACR,
+ NT_BUILTIN_MACRO.
+ (CPP_HASNODE_VALUE_IDX): Delete.
+ (union _cpp_hashnode_value): Adjust.
+ (struct cpp_hashnode): Likewise.
+ (cpp_macro_p, cpp_user_macro_p, cpp_builtin_macro_p): New.
+ * internal.h (_cpp_mark_macro_used): Use cpp_user_macro_p.
+ * directives.c (do_undef, do_pragma_poison, do_ifdef, do_ifndef)
+ (cpp_pop_definition): Use cpp_macro_p and friends.
+ (doassert): Adjust.
+ * expr.c (parse_defined): Use cpp_macro_p.
+ * files.c (should_stack_file): Likewise.
+ * identifiers.c (cpp_defined): Likewise.
+ * init.c (cpp_init_special_builtins): Adjust.
+ * lex.c (is_macro): Use cpp_macro_p.
+ * macro.c (cpp_warn_if_unused_macro, enter_macro_context)
+ (warn_of_redefinition, _cpp_create_definition): Use cpp_macro_p
+ and friends.
+ (_cpp_notify_macro_use): Adjust.
+ (cpp_macro_p): Delete old definition.
+ (cp_fun_like_macro_p): Use cpp_user_macro_p.
+ (cpp_macro_definition): Likewise.
+ * pch.c (write_macdef, count_defs, write_defs, save_macros): Adjust.
+ * traditional.c (fun_loke_macro, maybe_start_funlike)
+ (_cpp_scan_out_logical_line, push_replacement_text): Use
+ cpp_macro_p and friends.
+ gcc/c-family/
+ * c-ada-spec.c (count_ada_macro, store_ada_macro): Use cpp_user_macro_p.
+ * c-ppoutput.c (cb_used_define, dump_macro): Likewise.
+ * c-spellcheck.cc (should_suggest_as_macro_p): Likewise.
+ gcc/
+ * config/powerpcspe/powerpcspe-c.c (rs6000_macro_to_expand): Adjust.
+ * config/rs6000/rs6000-c.c (rs6000_macro_to_expand): Adjust.
+ gcc/cp/
+ * name-lookup.c (lookup_name_fuzzy): Use cpp_user_macro_p.
+ gcc/fortran/
+ * cpp.c (dump_macro): Use cpp_user_macro_p.
+
libcpp/
* internal.h (_cpp_notify_macro_use): Declare.
(_cpp_maybe_notify_macro_use): Define.
count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node,
void *v ATTRIBUTE_UNUSED)
{
- if (cpp_macro_p (node) && *NODE_NAME (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)
store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED,
cpp_hashnode *node, void *macros)
{
- if (cpp_macro_p (node) && *NODE_NAME (node) != '_')
+ if (cpp_user_macro_p (node) && *NODE_NAME (node) != '_')
{
const cpp_macro *macro = node->value.macro;
if (macro->count
cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED,
cpp_hashnode *node)
{
- if (cpp_macro_p (node))
+ if (cpp_user_macro_p (node))
{
macro_queue *q;
q = XNEW (macro_queue);
static int
dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
{
- if (cpp_macro_p (node))
+ /* asserts are distinguished by beginning with '#'. */
+ if (cpp_user_macro_p (node) && NODE_NAME(node)[0] != '#')
{
fputs ("#define ", print.outf);
fputs ((const char *) cpp_macro_definition (pfile, node),
static bool
should_suggest_as_macro_p (cpp_hashnode *hashnode)
{
- if (!cpp_macro_p (hashnode, true))
+ 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 (cpp_macro_p (hashnode, false)
+ if (cpp_user_macro_p (hashnode)
&& name_reserved_for_implementation_p ((const char *)hashnode->ident.str))
return false;
else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword)))
{
enum rid rid_code = (enum rid)(ident->rid_code);
- bool is_macro = cpp_macro_p (ident, true);
+ 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
else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword)))
{
enum rid rid_code = (enum rid)(ident->rid_code);
- bool is_macro = cpp_macro_p (ident, true);
+ 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
/* 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 && cpp_macro_p (macro))
- 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
static int
dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
{
- if (cpp_macro_p (node))
+ if (cpp_user_macro_p (node))
{
fputs ("#define ", print.outf);
fputs ((const char *) cpp_macro_definition (pfile, node),
/* 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 (cpp_macro_p (node))
{
if (node->flags & NODE_WARN)
cpp_error (pfile, CPP_DL_WARNING,
"undefining \"%s\"", NODE_NAME (node));
- else if ((node->type == NT_BUILTIN)
+ else if (cpp_builtin_macro_p (node)
&& CPP_OPTION (pfile, warn_builtin_macro_redefined))
cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED,
pfile->directive_line, 0,
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);
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_VOID
- || ((node->flags & NODE_CONDITIONAL) != 0));
+ skip = !cpp_macro_p (node) || (node->flags & NODE_CONDITIONAL);
_cpp_mark_macro_used (node);
_cpp_maybe_notify_macro_use (pfile, node);
if (pfile->cb.used)
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_VOID
- && ((node->flags & NODE_CONDITIONAL) == 0));
+ skip = (cpp_macro_p (node)
+ && !(node->flags & NODE_CONDITIONAL));
_cpp_mark_macro_used (node);
_cpp_maybe_notify_macro_use (pfile, node);
if (pfile->cb.used)
answer->parm.next = node->value.macro;
- node->type = NT_MACRO;
+ node->type = NT_USER_MACRO;
node->value.macro = answer;
check_eol (pfile, false);
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;
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;
}
/* 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. */
node = CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_NO_INSERT));
- /* If it's a 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
{
NT_VOID = 0, /* No definition yet. */
NT_MACRO_ARG, /* A macro arg. */
- NT_MACRO, /* A user macro or assert. */
- NT_BUILTIN /* A builtin macro. */
+ NT_USER_MACRO, /* A user macro or assert (#node). */
+ NT_BUILTIN_MACRO /* A builtin macro. */
};
/* Different flavors of builtin macro. _Pragma is an operator, but we
#define NODE_LEN(NODE) HT_LEN (&(NODE)->ident)
#define NODE_NAME(NODE) HT_STR (&(NODE)->ident)
-/* Specify which field, if any, of the union is used. */
-
-enum {
- NTV_MACRO,
- NTV_BUILTIN,
- NTV_ARGUMENT
-};
-
-#define CPP_HASHNODE_VALUE_IDX(HNODE) \
- ((HNODE).type == NT_MACRO_ARG ? NTV_ARGUMENT \
- : (HNODE).type == NT_BUILTIN ? NTV_BUILTIN \
- : NTV_MACRO)
-
/* The common part of an identifier node shared amongst all 3 C front
ends. Also used to store CPP identifiers, which are a superset of
identifiers in the grammatical sense. */
union GTY(()) _cpp_hashnode_value {
/* Macro or assert */
- cpp_macro * GTY((tag ("NTV_MACRO"))) macro;
+ cpp_macro * GTY((tag ("NT_USER_MACRO"))) macro;
/* Code for a builtin macro. */
- enum cpp_builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
+ enum cpp_builtin_type GTY ((tag ("NT_BUILTIN_MACRO"))) builtin;
/* Macro argument index. */
- unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index;
+ unsigned short GTY ((tag ("NT_MACRO_ARG"))) arg_index;
};
struct GTY(()) cpp_hashnode {
ENUM_BITFIELD(node_type) type : 6; /* CPP node type. */
unsigned int flags : 10; /* CPP flags. */
- union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
+ union _cpp_hashnode_value GTY ((desc ("%1.type"))) value;
};
/* A class for iterating through the source locations within a
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_macro_p (cpp_hashnode *node, bool builtin_ok = false);
+/* Although a macro may actually turn out to be an assert, they are
+ separated by namespace, in that the latter have special
+ '#'-starting names, that macros cannot have. We don't have to
+ check that. */
+inline bool cpp_user_macro_p (const cpp_hashnode *node)
+{
+ return node->type == NT_USER_MACRO;
+}
+inline bool cpp_builtin_macro_p (const cpp_hashnode *node)
+{
+ return node->type == NT_BUILTIN_MACRO;
+}
+inline bool cpp_macro_p (const cpp_hashnode *node)
+{
+ return node->type & NT_USER_MACRO;
+}
+
extern bool cpp_fun_like_macro_p (cpp_hashnode *);
extern const unsigned char *cpp_macro_definition (cpp_reader *,
cpp_hashnode *);
|| pfile->cb.has_attribute == NULL))
continue;
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
- hp->type = NT_BUILTIN;
+ hp->type = NT_BUILTIN_MACRO;
if (b->always_warn_if_redefined)
hp->flags |= NODE_WARN;
hp->value.builtin = (enum cpp_builtin_type) b->value;
#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)->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;
cpp_hashnode *result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table,
base, cur - base, hash, HT_NO_INSERT));
- return result ? result->type & NT_MACRO : false;
+ return result && cpp_macro_p (result);
}
/* Returns true if a literal suffix does not have the expected form
_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
void *v ATTRIBUTE_UNUSED)
{
- if (node->type == NT_MACRO)
+ if (cpp_user_macro_p (node))
{
cpp_macro *macro = node->value.macro;
function where set this flag to FALSE. */
pfile->about_to_expand_macro_p = true;
- if (node->type == NT_MACRO)
+ if (cpp_user_macro_p (node))
{
cpp_macro *macro = node->value.macro;
_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->type == NT_MACRO
+ cpp_user_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. */
/* Suppress warnings for builtins that lack the NODE_WARN flag,
unless Wbuiltin-macro-redefined. */
- if (node->type == NT_BUILTIN)
+ if (cpp_builtin_macro_p (node))
return CPP_OPTION (pfile, warn_builtin_macro_redefined);
/* Redefinitions of conditional (context-sensitive) macros, on
if (!macro)
return false;
- if (node->type & NT_MACRO)
+ if (cpp_macro_p (node))
{
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->type == NT_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)
+ 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");
}
/* Enter definition in hash table. */
- node->type = NT_MACRO;
+ node->type = NT_USER_MACRO;
node->value.macro = macro;
if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))
&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS")
node->flags |= NODE_USED;
switch (node->type)
{
- case NT_MACRO:
+ case NT_USER_MACRO:
{
cpp_macro *macro = node->value.macro;
if (macro->lazy)
}
/* FALLTHROUGH. */
- case NT_BUILTIN:
+ case NT_BUILTIN_MACRO:
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
break;
}
}
-/* Returns true if NODE is a macro. */
-bool
-cpp_macro_p (cpp_hashnode *node, bool builtin_ok)
-{
- if (node->type == NT_BUILTIN)
- return builtin_ok;
-
- if (node->type == NT_MACRO)
- return node->value.macro->kind != cmk_assert;
-
- return false;
-}
-
/* Returns true if NODE is a function-like macro. */
bool
cpp_fun_like_macro_p (cpp_hashnode *node)
{
- return cpp_macro_p (node) && node->value.macro->fun_like;
+ return cpp_user_macro_p (node) && node->value.macro->fun_like;
}
/* Returns the name, arguments and expansion of a macro, in a format
unsigned int i, len;
unsigned char *buffer;
- gcc_checking_assert (node->type == NT_MACRO);
+ gcc_checking_assert (cpp_user_macro_p (node));
const cpp_macro *macro = node->value.macro;
is_void = true;
goto poisoned;
- case NT_BUILTIN:
+ case NT_BUILTIN_MACRO:
return 1;
- case NT_MACRO:
+ case NT_USER_MACRO:
if (hn->value.macro->kind != cmk_assert)
{
poisoned:
switch (hn->type)
{
- case NT_BUILTIN:
+ case NT_BUILTIN_MACRO:
return 1;
- case NT_MACRO:
+ case NT_USER_MACRO:
if (hn->value.macro->kind == cmk_assert)
return 1;
switch (hn->type)
{
- case NT_BUILTIN:
+ case NT_BUILTIN_MACRO:
return 1;
- case NT_MACRO:
+ case NT_USER_MACRO:
if (hn->value.macro->kind == cmk_assert)
return 1;
{
struct save_macro_data *data = (struct save_macro_data *)data_p;
- if (h->type == NT_MACRO
- && h->value.macro->kind != cmk_assert)
+ if (cpp_user_macro_p (h) && h->value.macro->kind != cmk_assert)
{
if (data->count == data->array_size)
{
static inline bool
fun_like_macro (cpp_hashnode *node)
{
- if (node->type == NT_BUILTIN)
+ if (cpp_builtin_macro_p (node))
return node->value.builtin == BT_HAS_ATTRIBUTE;
else
return node->value.macro->fun_like;
struct fun_macro *macro)
{
unsigned int n;
- if (node->type == NT_BUILTIN)
+ if (cpp_builtin_macro_p (node))
n = 1;
else
n = node->value.macro->paramc;
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)
paren_depth--;
if (lex_state == ls_fun_close && paren_depth == 0)
{
- if (fmacro.node->type == NT_BUILTIN)
+ if (cpp_builtin_macro_p (fmacro.node))
{
/* Handle builtin function-like macros like
__has_attribute. The already parsed arguments
const uchar *text;
uchar *buf;
- if (node->type == NT_BUILTIN)
+ if (cpp_builtin_macro_p (node))
{
text = _cpp_builtin_macro_text (pfile, node);
len = ustrlen (text);