From patchwork Fri May 24 14:34:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1104947 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-501646-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="T8XhoCEu"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="cw+yR/6m"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 459TR92lj7z9s00 for ; Sat, 25 May 2019 00:34:45 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=oqtxIfn+AZiHjGc/Zih/L8PUq6P3E46+QX3XZGa4XwDssCkHXZ Auu4R/ljm3Bl/Q/7rY2uXum98MuoEtLyOrDHYBlmABxrr5cYU78XTe57XEUtL00I kFMmxIKy1gM2qw99v213jds3zUcEa5Z/UfQ1MwkL1Y3CUq2NvvjoSkLh8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=f9Nc3Du3zLo2U7TuRotKkXpUm9o=; b=T8XhoCEum3nSsYOfNhEK QYlPnohY+pNU557vhCc4Dfx6tRIjkJ9ndNb252GFMyrwAwBGXOljPWaisdL85ARq TkHJIDn9eYzyy5iyBP2FYZFNfWMM8UYmcy0d/GlS5yDzg0ftVrRq8WTll9C12kTa XZPILKYUU/I9DO1yFGaiMZU= Received: (qmail 98284 invoked by alias); 24 May 2019 14:34:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 98259 invoked by uid 89); 24 May 2019 14:34:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=harmful, Counter, DECL_NAME, TYPE_NAME X-HELO: mail-pl1-f172.google.com Received: from mail-pl1-f172.google.com (HELO mail-pl1-f172.google.com) (209.85.214.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 24 May 2019 14:34:34 +0000 Received: by mail-pl1-f172.google.com with SMTP id a5so4246406pls.12 for ; Fri, 24 May 2019 07:34:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:cc:from:subject:message-id:date:user-agent:mime-version :content-language; bh=nu1RPvAWZ6rCJsetyYBi13yk0+bj897mIa6oRj84W0E=; b=cw+yR/6mrkHIKjRgLrPza7lwFHNK6PHPfNhB5vuNYjh0xg7Fx1XI9dJrZhzYdYpq+O U2JqvTYdXKHEhHIl/IHvPyfqbrfVL8Jp/8AdiMwhGjMCiFMmy4b2OF1Zs/Fo/EtQ49pn KcLmP/yWZDuJP12dUMqg/S/geWkLbsJ7DW293SOVG+5BTH/dE3FeYd4aIOwWKYf5IiU7 f2o/vjgW+jBecaBCqdeZdw0Y38s03M9NdC0/HC+p1c7lIf+kFHAk9Zd+kd+AX9YkA/iw gIUpCeKTvr7w3EhdO+mroJFldF+gqQEZIu9thkC/fBTtY/NW7MbbPcfmm1ZxGBDFH2/I cgNg== Received: from ?IPv6:2620:10d:c0a3:1407:243f:1e7:d3b7:7bd9? ([2620:10d:c091:500::1:84aa]) by smtp.googlemail.com with ESMTPSA id c97sm5083563pje.5.2019.05.24.07.34.31 (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Fri, 24 May 2019 07:34:32 -0700 (PDT) To: GCC Patches Cc: ibuclaw@gdcproject.org, Jason Merrill From: Nathan Sidwell Subject: [PATCH] Commonize anon-name generation Message-ID: <9398e11d-d8d4-ed5a-3e9f-fa65bb7b3b96@acm.org> Date: Fri, 24 May 2019 10:34:29 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 Currently gcc/tree.c exports an anonymous name format string, and a predicate to detect identifiers of that form. The C++ and D FEs use those functions to create and check anonymous names. That seems a little duplicative. This patch changes tree.c to export an anonymous name generator, and uses a spare bit in IDENTIFIERs to mark them as anonymous, so no more strcmp to distinguish them. Then replaces the bespoke handling in the two front ends to use the new interface. While my original goal was to make there be only one anon-identifier in the C++ FE (because modules kind of would prefer not to have names depend on source ordering), I didn't get to that goal, I think we still sometimes place them in symbol tables. But this still seems a good thing. Are the common and D pieces ok? Jason, lambda class names are similarly anonymous, and I have a patch for them too. Would you prefer they just be from the same set of identifiers, with another C++-specific flag bit, or have a somewhat more distinct name, as they do now? (I.e. do you want to be able to distinguish lambdas when debugging just by looking at the string?) nathan 2019-05-24 Nathan Sidwell gcc/ * 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. Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 271599) +++ gcc/cp/class.c (working copy) @@ -6586,5 +6586,5 @@ find_flexarrays (tree t, flexmems_t *fme && 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 Index: gcc/cp/cp-lang.c =================================================================== --- gcc/cp/cp-lang.c (revision 271599) +++ gcc/cp/cp-lang.c (working copy) @@ -111,5 +111,5 @@ cxx_dwarf_name (tree t, int verbosity) 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) Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 271599) +++ gcc/cp/cp-tree.h (working copy) @@ -1938,5 +1938,5 @@ 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. */ @@ -6351,5 +6351,4 @@ 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); Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 271599) +++ gcc/cp/decl.c (working copy) @@ -10234,13 +10234,10 @@ 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)) @@ -14062,5 +14059,5 @@ xref_tag_1 (enum tag_types tag_code, tre 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); Index: gcc/cp/error.c =================================================================== --- gcc/cp/error.c (revision 271599) +++ gcc/cp/error.c (working copy) @@ -739,5 +739,5 @@ dump_aggr_type (cxx_pretty_printer *pp, } - if (name == 0 || anon_aggrname_p (name)) + if (!name || IDENTIFIER_ANON_P (name)) { if (flags & TFF_CLASS_KEY_OR_ENUM) Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 271599) +++ gcc/cp/name-lookup.c (working copy) @@ -3798,23 +3798,7 @@ constructor_name_p (tree name, tree type } -/* 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. */ @@ -5983,5 +5967,5 @@ consider_binding_level (tree name, best_ /* 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; Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 271599) +++ gcc/cp/pt.c (working copy) @@ -5502,5 +5502,5 @@ push_template_decl_real (tree decl, bool 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"); Index: gcc/d/types.cc =================================================================== --- gcc/d/types.cc (revision 271599) +++ gcc/d/types.cc (working copy) @@ -240,5 +240,5 @@ fixup_anonymous_offset (tree fields, tre 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); @@ -325,10 +325,5 @@ layout_aggregate_members (Dsymbols *memb 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; Index: gcc/lto-streamer-out.c =================================================================== --- gcc/lto-streamer-out.c (revision 271599) +++ gcc/lto-streamer-out.c (working copy) @@ -783,5 +783,5 @@ DFS::DFS_write_tree_body (struct output_ if (DECL_NAME (expr) && TREE_CODE (DECL_NAME (expr)) == IDENTIFIER_NODE - && anon_aggrname_p (DECL_NAME (expr))) + && IDENTIFIER_ANON_P (DECL_NAME (expr))) ; else @@ -1212,5 +1212,5 @@ hash_tree (struct streamer_tree_cache_d if (DECL_NAME (t) && TREE_CODE (DECL_NAME (t)) == IDENTIFIER_NODE - && anon_aggrname_p (DECL_NAME (t))) + && IDENTIFIER_ANON_P (DECL_NAME (t))) ; else Index: gcc/tree-streamer-out.c =================================================================== --- gcc/tree-streamer-out.c (revision 271599) +++ gcc/tree-streamer-out.c (working copy) @@ -580,5 +580,5 @@ write_ts_decl_minimal_tree_pointers (str 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 Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 271599) +++ gcc/tree.c (working copy) @@ -9746,38 +9746,30 @@ clean_symbol_name (char *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 */ -} +static GTY(()) unsigned anon_cnt = 0; /* Saved for PCH. */ + +/* Create a unique anonymous identifier. The identifier is still a + valid assembly label. */ -/* Return a format for an anonymous aggregate name. */ -const char * -anon_aggrname_format() +tree +make_anon_name () { -#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 */ + 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; } Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 271599) +++ gcc/tree.h (working copy) @@ -933,4 +933,9 @@ extern void omp_clause_range_check_faile ((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. */ @@ -5442,7 +5447,7 @@ 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. */