From: Nathan Sidwell Date: Tue, 28 May 2019 13:31:16 +0000 (+0000) Subject: [PATCH] Commonize anon-name generation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7daef9aceb80787d9fd64b4e110b175b4d9e5a9e;p=gcc.git [PATCH] Commonize anon-name generation https://gcc.gnu.org/ml/gcc-patches/2019-05/msg01699.html * tree.h (IDENTIFIER_ANON_P): New. (anon_aggrname_format, anon_aggname_p): Don't declare. (make_anon_name): Declare. * lto-streamer-out.c (DFS::DFS_write_tree_body): Use IDENTIFIER_ANON_P. (hash_tree): Likewise. * tree-streamer-out.c (write_ts_decl_minimal_tree): Likewise. * tree.c (anon_aggrname_p, anon_aggrname_format): Delete. (anon_cnt, make_anon_name): New. gcc/cp/ * cp-tree.h (make_anon_name): Drop declaration. (TYPE_UNNAMED_P): Use IDENTIFIER_ANON_P. * cp-lang.c (cxx_dwarf_name): Likewise. * class.c (find_flexarrays): Likewise. * decl.c (name_unnamed_type, xref_tag_1): Likewise. * error.c (dump_aggr_type): Likewise. * pt.c (push_template_decl_real): Likewise. * name-lookup.c (consider_binding_level): Likewise. (anon_cnt, make_anon_name): Delete. gcc/d/ * types.cc (fixup_anonymous_offset): Use IDENTIFIER_ANON_P. (layout_aggregate_members): Use make_anon_name. From-SVN: r271702 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad36bddd894..1bbe8950e99 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-05-28 Nathan Sidwell + + * tree.h (IDENTIFIER_ANON_P): New. + (anon_aggrname_format, anon_aggname_p): Don't declare. + (make_anon_name): Declare. + * lto-streamer-out.c (DFS::DFS_write_tree_body): Use IDENTIFIER_ANON_P. + (hash_tree): Likewise. + * tree-streamer-out.c (write_ts_decl_minimal_tree): Likewise. + * tree.c (anon_aggrname_p, anon_aggrname_format): Delete. + (anon_cnt, make_anon_name): New. + 2019-05-28 Martin Liska PR other/90315 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0c37f55fe25..001c53ee1fc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2019-05-28 Nathan Sidwell + + * cp-tree.h (make_anon_name): Drop declaration. + (TYPE_UNNAMED_P): Use IDENTIFIER_ANON_P. + * cp-lang.c (cxx_dwarf_name): Likewise. + * class.c (find_flexarrays): Likewise. + * decl.c (name_unnamed_type, xref_tag_1): Likewise. + * error.c (dump_aggr_type): Likewise. + * pt.c (push_template_decl_real): Likewise. + * name-lookup.c (consider_binding_level): Likewise. + (anon_cnt, make_anon_name): Delete. + 2019-05-25 Marek Polacek PR c++/90572 - wrong disambiguation in friend declaration. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index ed885a5a2c1..a2585a61f96 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6585,7 +6585,7 @@ find_flexarrays (tree t, flexmems_t *fmem, bool base_p, if (TREE_CODE (fld) == TYPE_DECL && DECL_IMPLICIT_TYPEDEF_P (fld) && CLASS_TYPE_P (TREE_TYPE (fld)) - && anon_aggrname_p (DECL_NAME (fld))) + && IDENTIFIER_ANON_P (DECL_NAME (fld))) { /* Check the nested unnamed type referenced via a typedef independently of FMEM (since it's not a data member of diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index 9dc3659c210..b725dece4bb 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -110,7 +110,7 @@ cxx_dwarf_name (tree t, int verbosity) gcc_assert (DECL_P (t)); if (DECL_NAME (t) - && (anon_aggrname_p (DECL_NAME (t)) || LAMBDA_TYPE_P (t))) + && (IDENTIFIER_ANON_P (DECL_NAME (t)) || LAMBDA_TYPE_P (t))) return NULL; if (verbosity >= 2) return decl_as_dwarf_string (t, diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fb5470dd8c2..7a74fd4fac5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1937,7 +1937,7 @@ enum languages { lang_c, lang_cplusplus }; /* Nonzero if NODE has no name for linkage purposes. */ #define TYPE_UNNAMED_P(NODE) \ - (OVERLOAD_TYPE_P (NODE) && anon_aggrname_p (TYPE_LINKAGE_IDENTIFIER (NODE))) + (OVERLOAD_TYPE_P (NODE) && IDENTIFIER_ANON_P (TYPE_LINKAGE_IDENTIFIER (NODE))) /* The _DECL for this _TYPE. */ #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) @@ -6350,7 +6350,6 @@ extern tree strip_fnptr_conv (tree); /* in name-lookup.c */ extern void maybe_push_cleanup_level (tree); -extern tree make_anon_name (void); extern tree maybe_push_decl (tree); extern tree current_decl_namespace (void); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 19d14a6a5e9..5b22f65ec8d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10233,15 +10233,12 @@ name_unnamed_type (tree type, tree decl) /* Replace the anonymous name with the real name everywhere. */ for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - { - if (anon_aggrname_p (TYPE_IDENTIFIER (t))) - /* We do not rename the debug info representing the - unnamed tagged type because the standard says in - [dcl.typedef] that the naming applies only for - linkage purposes. */ - /*debug_hooks->set_name (t, decl);*/ - TYPE_NAME (t) = decl; - } + if (IDENTIFIER_ANON_P (TYPE_IDENTIFIER (t))) + /* We do not rename the debug info representing the unnamed + tagged type because the standard says in [dcl.typedef] that + the naming applies only for linkage purposes. */ + /*debug_hooks->set_name (t, decl);*/ + TYPE_NAME (t) = decl; if (TYPE_LANG_SPECIFIC (type)) TYPE_WAS_UNNAMED (type) = 1; @@ -14061,7 +14058,7 @@ xref_tag_1 (enum tag_types tag_code, tree name, /* In case of anonymous name, xref_tag is only called to make type node and push name. Name lookup is not required. */ tree t = NULL_TREE; - if (scope != ts_lambda && !anon_aggrname_p (name)) + if (scope != ts_lambda && !IDENTIFIER_ANON_P (name)) t = lookup_and_check_tag (tag_code, name, scope, template_header_p); if (t == error_mark_node) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 4a0aed2b725..5e7c36d8698 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -738,7 +738,7 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags) name = DECL_NAME (name); } - if (name == 0 || anon_aggrname_p (name)) + if (!name || IDENTIFIER_ANON_P (name)) { if (flags & TFF_CLASS_KEY_OR_ENUM) pp_string (pp, M_("")); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 0dcaf651656..242e30f8a12 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3797,25 +3797,9 @@ constructor_name_p (tree name, tree type) return false; } -/* Counter used to create anonymous type names. */ - -static GTY(()) int anon_cnt; - -/* Return an IDENTIFIER which can be used as a name for - unnamed structs and unions. */ - -tree -make_anon_name (void) -{ - char buf[32]; - - sprintf (buf, anon_aggrname_format (), anon_cnt++); - return get_identifier (buf); -} - -/* This code is practically identical to that for creating - anonymous names, but is just used for lambdas instead. This isn't really - necessary, but it's convenient to avoid treating lambdas like other +/* This code is practically identical to that for creating anonymous + names, but is just used for lambdas instead. This isn't really + necessary, but it's convenient to avoid mistaking lambdas for other unnamed types. */ static GTY(()) int lambda_cnt = 0; @@ -5982,7 +5966,7 @@ consider_binding_level (tree name, best_match &bm, /* Don't suggest names that are for anonymous aggregate types, as they are an implementation detail generated by the compiler. */ - if (anon_aggrname_p (suggestion)) + if (IDENTIFIER_ANON_P (suggestion)) continue; const char *suggestion_str = IDENTIFIER_POINTER (suggestion); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 592adfcf5c1..e52668ab49d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5501,7 +5501,7 @@ push_template_decl_real (tree decl, bool is_friend) if (DECL_CLASS_SCOPE_P (decl)) member_template_p = true; if (TREE_CODE (decl) == TYPE_DECL - && anon_aggrname_p (DECL_NAME (decl))) + && IDENTIFIER_ANON_P (DECL_NAME (decl))) { error ("template class without a name"); return error_mark_node; diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index b6ac2f8f080..800dcb0abbc 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,8 @@ +2019-05-24 Nathan Sidwell + + * types.cc (fixup_anonymous_offset): Use IDENTIFIER_ANON_P. + (layout_aggregate_members): Use make_anon_name. + 2019-05-16 Martin Sebor * d-builtins.cc (d_init_builtins): Quote keywords, operators, diff --git a/gcc/d/types.cc b/gcc/d/types.cc index cdbfbb7d003..8f0aa37f578 100644 --- a/gcc/d/types.cc +++ b/gcc/d/types.cc @@ -239,7 +239,7 @@ fixup_anonymous_offset (tree fields, tree offset) /* Traverse all nested anonymous aggregates to update their offset. Set the anonymous decl offset to its first member. */ tree ftype = TREE_TYPE (fields); - if (TYPE_NAME (ftype) && anon_aggrname_p (TYPE_IDENTIFIER (ftype))) + if (TYPE_NAME (ftype) && IDENTIFIER_ANON_P (TYPE_IDENTIFIER (ftype))) { tree vfields = TYPE_FIELDS (ftype); fixup_anonymous_offset (vfields, offset); @@ -324,12 +324,7 @@ layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p) AnonDeclaration *ad = sym->isAnonDeclaration (); if (ad != NULL) { - /* Use a counter to create anonymous type names. */ - static int anon_cnt = 0; - char buf[32]; - sprintf (buf, anon_aggrname_format (), anon_cnt++); - - tree ident = get_identifier (buf); + tree ident = make_anon_name (); tree type = make_node (ad->isunion ? UNION_TYPE : RECORD_TYPE); ANON_AGGR_TYPE_P (type) = 1; d_keep (type); diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index e22a9e596e1..b1084f4d3c5 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -782,7 +782,7 @@ DFS::DFS_write_tree_body (struct output_block *ob, /* Drop names that were created for anonymous entities. */ if (DECL_NAME (expr) && TREE_CODE (DECL_NAME (expr)) == IDENTIFIER_NODE - && anon_aggrname_p (DECL_NAME (expr))) + && IDENTIFIER_ANON_P (DECL_NAME (expr))) ; else DFS_follow_tree_edge (DECL_NAME (expr)); @@ -1211,7 +1211,7 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map *map, /* Drop names that were created for anonymous entities. */ if (DECL_NAME (t) && TREE_CODE (DECL_NAME (t)) == IDENTIFIER_NODE - && anon_aggrname_p (DECL_NAME (t))) + && IDENTIFIER_ANON_P (DECL_NAME (t))) ; else visit (DECL_NAME (t)); diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c index 3f619e830a7..b89cb6547db 100644 --- a/gcc/tree-streamer-out.c +++ b/gcc/tree-streamer-out.c @@ -579,7 +579,7 @@ write_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr, /* Drop names that were created for anonymous entities. */ if (DECL_NAME (expr) && TREE_CODE (DECL_NAME (expr)) == IDENTIFIER_NODE - && anon_aggrname_p (DECL_NAME (expr))) + && IDENTIFIER_ANON_P (DECL_NAME (expr))) stream_write_tree (ob, NULL_TREE, ref_p); else stream_write_tree (ob, DECL_NAME (expr), ref_p); diff --git a/gcc/tree.c b/gcc/tree.c index 9a8f5e56742..8ca72110526 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9747,40 +9747,32 @@ clean_symbol_name (char *p) *p = '_'; } -/* For anonymous aggregate types, we need some sort of name to - hold on to. In practice, this should not appear, but it should - not be harmful if it does. */ -bool -anon_aggrname_p(const_tree id_node) -{ -#ifndef NO_DOT_IN_LABEL - return (IDENTIFIER_POINTER (id_node)[0] == '.' - && IDENTIFIER_POINTER (id_node)[1] == '_'); -#else /* NO_DOT_IN_LABEL */ -#ifndef NO_DOLLAR_IN_LABEL - return (IDENTIFIER_POINTER (id_node)[0] == '$' \ - && IDENTIFIER_POINTER (id_node)[1] == '_'); -#else /* NO_DOLLAR_IN_LABEL */ -#define ANON_AGGRNAME_PREFIX "__anon_" - return (!strncmp (IDENTIFIER_POINTER (id_node), ANON_AGGRNAME_PREFIX, - sizeof (ANON_AGGRNAME_PREFIX) - 1)); -#endif /* NO_DOLLAR_IN_LABEL */ -#endif /* NO_DOT_IN_LABEL */ -} - -/* Return a format for an anonymous aggregate name. */ -const char * -anon_aggrname_format() -{ -#ifndef NO_DOT_IN_LABEL - return "._%d"; -#else /* NO_DOT_IN_LABEL */ -#ifndef NO_DOLLAR_IN_LABEL - return "$_%d"; -#else /* NO_DOLLAR_IN_LABEL */ - return "__anon_%d"; -#endif /* NO_DOLLAR_IN_LABEL */ -#endif /* NO_DOT_IN_LABEL */ +static GTY(()) unsigned anon_cnt = 0; /* Saved for PCH. */ + +/* Create a unique anonymous identifier. The identifier is still a + valid assembly label. */ + +tree +make_anon_name () +{ + const char *fmt = +#if !defined (NO_DOT_IN_LABEL) + "." +#elif !defined (NO_DOLLAR_IN_LABEL) + "$" +#else + "_" +#endif + "_anon_%d"; + + char buf[24]; + int len = snprintf (buf, sizeof (buf), fmt, anon_cnt++); + gcc_checking_assert (len < int (sizeof (buf))); + + tree id = get_identifier_with_length (buf, len); + IDENTIFIER_ANON_P (id) = true; + + return id; } /* Generate a name for a special-purpose function. diff --git a/gcc/tree.h b/gcc/tree.h index 72544b63d79..7009c673a1c 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -932,6 +932,11 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define TREE_DEPRECATED(NODE) \ ((NODE)->base.deprecated_flag) +/* Nonzero indicates an IDENTIFIER_NODE that names an anonymous + aggregate, (as created by anon_aggr_name_format). */ +#define IDENTIFIER_ANON_P(NODE) \ + (IDENTIFIER_NODE_CHECK (NODE)->base.private_flag) + /* Nonzero in an IDENTIFIER_NODE if the name is a local alias, whose uses are to be substituted for uses of the TREE_CHAINed identifier. */ #define IDENTIFIER_TRANSPARENT_ALIAS(NODE) \ @@ -5441,9 +5446,9 @@ target_opts_for_fn (const_tree fndecl) /* For anonymous aggregate types, we need some sort of name to hold on to. In practice, this should not appear, but it should - not be harmful if it does. */ -extern const char *anon_aggrname_format(); -extern bool anon_aggrname_p (const_tree); + not be harmful if it does. Identifiers returned will be + IDENTIFIER_ANON_P. */ +extern tree make_anon_name (); /* The tree and const_tree overload templates. */ namespace wi