From: Nathan Sidwell Date: Mon, 20 Aug 2018 16:32:29 +0000 (+0000) Subject: [CPP PATCH] node type X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a570d97f5b8612ad2756333e5f21098be64057df;p=gcc.git [CPP PATCH] node type https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01164.html * include/cpplib.h (NODE_BUILTIN, NODE_MACRO_ARG): Delete. Renumber others. (enum node_type): Replace NT_MACRO with NT_USER_MACRO, NT_BUILTIN_MACRO, NT_MACRO_ARG. Delete NT_ASSERTION. (NTV_MACRO, NTV_ANSWER, NTV_BUILTIN, NTV_ARGUMENT, NTV_NONE): Delete. (CPP_HASHNODE_VALUE_IDX): Delete. (union _cpp_hashnode_value): GTY tag from enum node_type directly. (struct cpp_hashnode): Adjust GTY desc for value field. (cpp_user_macro_p, cpp_builtin_macro_p, cpp_macro_p): Adjust. * directives.c (undefine_macros): Clear value.anwers, adjust flag clearing. (_cpp_test_assertion): No need to check NT_ASSERTION. (do_assert, do_unassert): Likewise. * init.c (cpp_init_special_builtins): Set type not flags. * macro.c (struct macro_arg_saved_data): Add type field. (cpp_get_token_1): Check type not NT_VOID. (_cpp_free_definition): Adjust flag clearing. Nullify value.answers. (_cpp_save_parameter, _cpp_unsave_parameters): Save and restore type. (lex_expansion_token): Check type not flags. (_cpp_create_definition): Set type to NT_USER_MACRO. (_cpp_notify_macro_use): Adjust type checking. * pch.c (write_macdef, count_defs, write_defs, cpp_valid_state) (save_macros): Adjust node type/flag handling. * traditional.c (_cpp_scan_out_logical_line): Check type not flags. From-SVN: r263667 --- diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 01cc2508678..8998c0dace9 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,5 +1,33 @@ 2018-08-20 Nathan Sidwell + * include/cpplib.h (NODE_BUILTIN, NODE_MACRO_ARG): Delete. + Renumber others. + (enum node_type): Replace NT_MACRO with NT_USER_MACRO, + NT_BUILTIN_MACRO, NT_MACRO_ARG. Delete NT_ASSERTION. + (NTV_MACRO, NTV_ANSWER, NTV_BUILTIN, NTV_ARGUMENT, NTV_NONE): + Delete. + (CPP_HASHNODE_VALUE_IDX): Delete. + (union _cpp_hashnode_value): GTY tag from enum node_type directly. + (struct cpp_hashnode): Adjust GTY desc for value field. + (cpp_user_macro_p, cpp_builtin_macro_p, cpp_macro_p): Adjust. + * directives.c (undefine_macros): Clear value.anwers, adjust flag + clearing. + (_cpp_test_assertion): No need to check NT_ASSERTION. + (do_assert, do_unassert): Likewise. + * init.c (cpp_init_special_builtins): Set type not flags. + * macro.c (struct macro_arg_saved_data): Add type field. + (cpp_get_token_1): Check type not NT_VOID. + (_cpp_free_definition): Adjust flag clearing. Nullify + value.answers. + (_cpp_save_parameter, _cpp_unsave_parameters): Save and restore + type. + (lex_expansion_token): Check type not flags. + (_cpp_create_definition): Set type to NT_USER_MACRO. + (_cpp_notify_macro_use): Adjust type checking. + * pch.c (write_macdef, count_defs, write_defs, cpp_valid_state) + (save_macros): Adjust node type/flag handling. + * traditional.c (_cpp_scan_out_logical_line): Check type not flags. + * directives.c (do_undef): Use cpp_macro_p & cpp_builtin_macro_p. * include/cpplib.h (enum cpp_macro_kind): Remove trailing comma. (cpp_fun_like_macro_p): Make inline, define. diff --git a/libcpp/directives.c b/libcpp/directives.c index f04ed7cf2c1..f7c460d2f83 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -695,7 +695,8 @@ undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h, /* 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->value.answers = NULL; + h->flags &= ~(NODE_POISONED|NODE_DISABLED|NODE_USED); return 1; } @@ -2217,9 +2218,10 @@ parse_answer (cpp_reader *pfile, int type, source_location pred_loc, } /* Parses an assertion directive of type TYPE, returning a pointer to - the hash node of the predicate, or 0 on error. If an answer was - supplied, it is placed in EXP_PTR & EXP_COUNT, which is otherwise - set to 0. */ + the hash node of the predicate, or 0 on error. The node is + guaranteed to be disjoint from the macro namespace, so can only + have type 'NT_VOID'. If an answer was supplied, it is placed in + *ANSWER_PTR, which is otherwise set to 0. */ static cpp_hashnode * parse_assertion (cpp_reader *pfile, int type, cpp_macro **answer_ptr) { @@ -2294,7 +2296,7 @@ _cpp_test_assertion (cpp_reader *pfile, unsigned int *value) if (node) { - if (node->type == NT_ASSERTION) + if (node->value.answers) *value = !answer || *find_answer (node, answer); } else if (pfile->cur_token[-1].type == CPP_EOF) @@ -2315,7 +2317,7 @@ do_assert (cpp_reader *pfile) { /* Place the new answer in the answer list. First check there is not a duplicate. */ - if (node->type == NT_ASSERTION && *find_answer (node, answer)) + if (*find_answer (node, answer)) { cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted", NODE_NAME (node) + 1); @@ -2327,10 +2329,8 @@ do_assert (cpp_reader *pfile) (pfile, sizeof (cpp_macro) - sizeof (cpp_token) + sizeof (cpp_token) * answer->count); - if (node->type == NT_ASSERTION) - answer->parm.next = node->value.answers; - - node->type = NT_ASSERTION; + /* Chain into the list. */ + answer->parm.next = node->value.answers; node->value.answers = answer; check_eol (pfile, false); @@ -2345,7 +2345,7 @@ do_unassert (cpp_reader *pfile) cpp_hashnode *node = parse_assertion (pfile, T_UNASSERT, &answer); /* It isn't an error to #unassert something that isn't asserted. */ - if (node && node->type == NT_ASSERTION) + if (node) { if (answer) { @@ -2353,12 +2353,7 @@ do_unassert (cpp_reader *pfile) /* Remove the assert from the list. */ if (cpp_macro *temp = *p) - { - *p = temp->parm.next; - /* Did we free the last answer? */ - if (!*p) - node->type = NT_VOID; - } + *p = temp->parm.next; check_eol (pfile, false); } diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index b784e0facd0..e7a933b1787 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -742,14 +742,9 @@ struct GTY(()) cpp_macro { } GTY ((desc ("%1.kind == cmk_traditional"))) exp; }; -/* The structure of a node in the hash table. The hash table has - entries for all identifiers: either macros defined by #define - commands (type NT_MACRO), assertions created with #assert - (NT_ASSERTION), or neither of the above (NT_VOID). Builtin macros - like __LINE__ are flagged NODE_BUILTIN. Poisoned identifiers are - flagged NODE_POISONED. NODE_OPERATOR (C++ only) indicates an - identifier that behaves like an operator such as "xor". - NODE_DIAGNOSTIC is for speed in lex_token: it indicates a +/* Poisoned identifiers are flagged NODE_POISONED. NODE_OPERATOR (C++ + only) indicates an identifier that behaves like an operator such as + "xor". NODE_DIAGNOSTIC is for speed in lex_token: it indicates a diagnostic may be required for this node. Currently this only applies to __VA_ARGS__, poisoned identifiers, and -Wc++-compat warnings about NODE_OPERATOR. */ @@ -757,21 +752,21 @@ struct GTY(()) cpp_macro { /* 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. */ +#define NODE_DIAGNOSTIC (1 << 2) /* Possible diagnostic when lexed. */ +#define NODE_WARN (1 << 3) /* Warn if redefined or undefined. */ +#define NODE_DISABLED (1 << 4) /* A disabled macro. */ +#define NODE_USED (1 << 5) /* Dumped with -dU. */ +#define NODE_CONDITIONAL (1 << 6) /* Conditional macro */ +#define NODE_WARN_OPERATOR (1 << 7) /* Warn about C++ named operator. */ /* Different flavors of hash node. */ enum node_type { - NT_VOID = 0, /* No definition yet. */ - NT_MACRO, /* A macro of some form. */ - NT_ASSERTION /* Predicate for #assert. */ + NT_VOID = 0, /* Maybe an assert? */ + NT_MACRO_ARG, /* A macro arg. */ + NT_USER_MACRO, /* A user macro. */ + NT_BUILTIN_MACRO, /* A builtin macro. */ + NT_MACRO_MASK = NT_USER_MACRO /* Mask for either macro kind. */ }; /* Different flavors of builtin macro. _Pragma is an operator, but we @@ -796,36 +791,19 @@ enum cpp_builtin_type #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_ANSWER, - NTV_BUILTIN, - NTV_ARGUMENT, - NTV_NONE -}; - -#define CPP_HASHNODE_VALUE_IDX(HNODE) \ - ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \ - : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \ - ? NTV_BUILTIN : NTV_MACRO) \ - : HNODE.type == NT_ASSERTION ? NTV_ANSWER \ - : NTV_NONE) - /* 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 { - /* If a macro. */ - cpp_macro * GTY((tag ("NTV_MACRO"))) macro; - /* Answers to an assertion. */ - cpp_macro * GTY ((tag ("NTV_ANSWER"))) answers; + /* Assert (maybe NULL) */ + cpp_macro * GTY((tag ("NT_VOID"))) answers; + /* Macro (never NULL) */ + 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 { @@ -838,7 +816,7 @@ 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 @@ -961,15 +939,16 @@ extern const cpp_token *cpp_get_token_with_location (cpp_reader *, source_location *); inline bool cpp_user_macro_p (const cpp_hashnode *node) { - return node->type == NT_MACRO && !(node->flags & NODE_BUILTIN); + return node->type == NT_USER_MACRO; + } inline bool cpp_builtin_macro_p (const cpp_hashnode *node) { - return node->flags & NODE_BUILTIN; + return node->type == NT_BUILTIN_MACRO; } inline bool cpp_macro_p (const cpp_hashnode *node) { - return node->type == NT_MACRO; + return node->type & NT_MACRO_MASK; } /* Returns true if NODE is a function-like user macro. */ inline bool cpp_fun_like_macro_p (cpp_hashnode *node) diff --git a/libcpp/init.c b/libcpp/init.c index d1697fdec1c..32a59565174 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -480,8 +480,7 @@ cpp_init_special_builtins (cpp_reader *pfile) || 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_MACRO; if (b->always_warn_if_redefined) hp->flags |= NODE_WARN; hp->value.builtin = (enum cpp_builtin_type) b->value; diff --git a/libcpp/macro.c b/libcpp/macro.c index 123f63d1177..3629e83cecf 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -85,8 +85,9 @@ struct macro_arg_token_iter 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 = @@ -2730,7 +2731,7 @@ cpp_get_token_1 (cpp_reader *pfile, source_location *location) 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)) @@ -3040,8 +3041,8 @@ _cpp_free_definition (cpp_hashnode *h) { /* 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->value.answers = NULL; + h->flags &= ~(NODE_DISABLED | NODE_USED); } /* Save parameter NODE (spelling SPELLING) to the parameter list of @@ -3051,7 +3052,7 @@ _cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node, cpp_hashnode *spelling) { /* Constraint 6.10.3.6 - duplicate parameter names. */ - if (node->flags & NODE_MACRO_ARG) + if (node->type == NT_MACRO_ARG) { cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"", NODE_NAME (node)); @@ -3069,13 +3070,14 @@ _cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node, macro_arg_saved_data *saved = (macro_arg_saved_data *)pfile->macro_buffer; 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 *)); ((cpp_hashnode **)base)[n] = spelling; /* Morph into a macro arg. */ - node->flags |= NODE_MACRO_ARG; + node->type = NT_MACRO_ARG; /* Index is 1 based. */ node->value.arg_index = n + 1; @@ -3093,8 +3095,8 @@ _cpp_unsave_parameters (cpp_reader *pfile, unsigned n) &((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->flags &= ~NODE_MACRO_ARG; } } @@ -3109,6 +3111,7 @@ _cpp_unsave_parameters (cpp_reader *pfile, unsigned n) | name '...' | '...' */ + static bool parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr) { @@ -3232,9 +3235,9 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) pfile->cur_token = saved_cur_token; /* Is this a parameter? */ - if (token->type == CPP_NAME - && (token->val.node.node->flags & NODE_MACRO_ARG) != 0) + if (token->type == CPP_NAME && token->val.node.node->type == NT_MACRO_ARG) { + /* Morph into a parameter reference. */ cpp_hashnode *spelling = token->val.node.spelling; token->type = CPP_MACRO_ARG; token->val.macro_arg.arg_no = token->val.node.node->value.arg_index; @@ -3527,7 +3530,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) } /* 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") @@ -3565,17 +3568,18 @@ _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)) - { - cpp_macro *macro = node->value.macro; - if (macro->lazy) - { - pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1); - macro->lazy = 0; - } - } + case NT_USER_MACRO: + { + cpp_macro *macro = node->value.macro; + if (macro->lazy) + { + pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1); + macro->lazy = 0; + } + } + /* FALLTHROUGH. */ + case NT_BUILTIN_MACRO: if (pfile->cb.used_define) pfile->cb.used_define (pfile, pfile->directive_line, node); break; diff --git a/libcpp/pch.c b/libcpp/pch.c index 47b99c11981..04d7094b068 100644 --- a/libcpp/pch.c +++ b/libcpp/pch.c @@ -50,48 +50,47 @@ static int write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) { FILE *f = (FILE *) file_p; + bool is_void = false; switch (hn->type) { case NT_VOID: if (! (hn->flags & NODE_POISONED)) return 1; - /* XXX Really fallthru? */ - /* FALLTHRU */ + is_void = true; + goto poisoned; - case NT_MACRO: - if (hn->flags & NODE_BUILTIN) - return 1; - - { - struct macrodef_struct s; - const unsigned char *defn; + case NT_BUILTIN_MACRO: + return 1; - s.name_length = NODE_LEN (hn); - s.flags = hn->flags & NODE_POISONED; + case NT_USER_MACRO: + if (hn->value.macro->kind != cmk_assert) + { + poisoned: + struct macrodef_struct s; + const unsigned char *defn; - if (hn->type == NT_MACRO) - { - defn = cpp_macro_definition (pfile, hn); - s.definition_length = ustrlen (defn); - } - else - { - defn = NODE_NAME (hn); - s.definition_length = s.name_length; - } + s.name_length = NODE_LEN (hn); + s.flags = hn->flags & NODE_POISONED; - if (fwrite (&s, sizeof (s), 1, f) != 1 - || fwrite (defn, 1, s.definition_length, f) != s.definition_length) - { - cpp_errno (pfile, CPP_DL_ERROR, - "while writing precompiled header"); - return 0; - } - } - return 1; + if (is_void) + { + defn = NODE_NAME (hn); + s.definition_length = s.name_length; + } + else + { + defn = cpp_macro_definition (pfile, hn); + s.definition_length = ustrlen (defn); + } - case NT_ASSERTION: - /* Not currently implemented. */ + if (fwrite (&s, sizeof (s), 1, f) != 1 + || fwrite (defn, 1, s.definition_length, f) != s.definition_length) + { + cpp_errno (pfile, CPP_DL_ERROR, + "while writing precompiled header"); + return 0; + } + } return 1; default: @@ -226,8 +225,11 @@ count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) switch (hn->type) { - case NT_MACRO: - if (hn->flags & NODE_BUILTIN) + case NT_BUILTIN_MACRO: + return 1; + + case NT_USER_MACRO: + if (hn->value.macro->kind == cmk_assert) return 1; /* fall through. */ @@ -248,10 +250,6 @@ count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) } return 1; - case NT_ASSERTION: - /* Not currently implemented. */ - return 1; - default: abort (); } @@ -265,8 +263,11 @@ write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) switch (hn->type) { - case NT_MACRO: - if (hn->flags & NODE_BUILTIN) + case NT_BUILTIN_MACRO: + return 1; + + case NT_USER_MACRO: + if (hn->value.macro->kind == cmk_assert) return 1; /* fall through. */ @@ -287,10 +288,6 @@ write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) } return 1; - case NT_ASSERTION: - /* Not currently implemented. */ - return 1; - default: abort (); } @@ -621,7 +618,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) 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 @@ -758,8 +755,7 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) { struct save_macro_data *data = (struct save_macro_data *)data_p; - if (h->type != NT_VOID - && (h->flags & NODE_BUILTIN) == 0) + if (cpp_user_macro_p (h)) { if (data->count == data->array_size) { @@ -767,28 +763,14 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size)); } - switch (h->type) - { - case NT_ASSERTION: - /* Not currently implemented. */ - return 1; - - case NT_MACRO: - { - const uchar * defn = cpp_macro_definition (r, h); - size_t defnlen = ustrlen (defn); + const uchar * defn = cpp_macro_definition (r, h); + size_t defnlen = ustrlen (defn); - data->defns[data->count] = (uchar *) xmemdup (defn, defnlen, - defnlen + 2); - data->defns[data->count][defnlen] = '\n'; - } - break; - - default: - abort (); - } + data->defns[data->count] = (uchar *) xmemdup (defn, defnlen, defnlen + 2); + data->defns[data->count][defnlen] = '\n'; data->count++; } + return 1; } diff --git a/libcpp/traditional.c b/libcpp/traditional.c index 0c42b25d199..51c3e3522e2 100644 --- a/libcpp/traditional.c +++ b/libcpp/traditional.c @@ -545,7 +545,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro, goto new_context; } } - else if (macro && (node->flags & NODE_MACRO_ARG) != 0) + else if (macro && node->type == NT_MACRO_ARG) { /* Found a parameter in the replacement text of a #define. Remove its name from the output. */