+2019-05-28 Nathan Sidwell <nathan@acm.org>
+
+ * 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 <mliska@suse.cz>
PR other/90315
+2019-05-28 Nathan Sidwell <nathan@acm.org>
+
+ * 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 <polacek@redhat.com>
PR c++/90572 - wrong disambiguation in friend declaration.
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
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,
/* 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)))
/* 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);
/* 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;
/* 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)
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_("<unnamed>"));
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;
/* 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);
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;
+2019-05-24 Nathan Sidwell <nathan@acm.org>
+
+ * types.cc (fixup_anonymous_offset): Use IDENTIFIER_ANON_P.
+ (layout_aggregate_members): Use make_anon_name.
+
2019-05-16 Martin Sebor <msebor@redhat.com>
* d-builtins.cc (d_init_builtins): Quote keywords, operators,
/* 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);
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);
/* 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));
/* 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));
/* 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);
*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.
#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) \
/* 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