From patchwork Fri May 31 13:23:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1108351 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-502075-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="pWE4g/m1"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="f+/26V/b"; 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 45FlXF5g56z9s3Z for ; Fri, 31 May 2019 23:23:53 +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 :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=lwObzBUlOJDvoXTiNdXPnxVsugqG4yl4pXGLzthkJKDuHcASRd /BwxprXl6qX/P32kP24u+ZOttDQJSB6gjK4FIr+3+N/o1MUBL/itOAy4J4ybuXrw dwUy1fK12ORTXOqHEdV1kiXnTnSlGLTG9wV9SrXxkkLCKQpo0DD5gFHIM= 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 :from:subject:message-id:date:mime-version:content-type; s= default; bh=oUisHAVbhe/aVgJAo6GexwPaDOw=; b=pWE4g/m1k6Hj1tmdklxu YUmHaIPAN/Rw3M3GA7TXI9vQacdC7y9ZIuff0yBcekayS/FGgb0IW6vZaF1ctDRI U/vWdVSSkphLm9rGAbsDJMuszQ5efUzURoTOq7zL8BNAnZd7a9yFdjLt/wGLAM7X mJE9ZPHbftEmF3Od1WCt91o= Received: (qmail 101516 invoked by alias); 31 May 2019 13:23:46 -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 101507 invoked by uid 89); 31 May 2019 13:23:46 -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=Unique, practically, smell X-HELO: mail-pl1-f181.google.com Received: from mail-pl1-f181.google.com (HELO mail-pl1-f181.google.com) (209.85.214.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 31 May 2019 13:23:44 +0000 Received: by mail-pl1-f181.google.com with SMTP id g69so4021404plb.7 for ; Fri, 31 May 2019 06:23:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=OHhwm+SGJlMRBvP6xjarhW41KQeq1L+OOtYYwSXoiwg=; b=f+/26V/bnehpV7ujGi00yZDSpowKiFnwpsnNwvQG1SyJlG0YUWkH8rTpt6DUaoH3zZ IPIXGuImZQ1Q7BS6P6qEV4jvqo5wokwCAnjYQtWj/er1wYlVG8s4f6coMX51/YRnQAwy xg/90G6uLvZ3ufNZzOOc55ZnfyDk6lqmoJw89MAVO7KcHcwSUjUnglx9hYB4Fyob7dgq 12GwJYmFIYSaMtCyGqCT4QGU5lqmF0wmkoQWNnvLk0tOmDCdt+dCfGsUEp0TdC1QozVi f3Pcpdehv2hMrjlMVmoJK59IdNJfUt3qNNUKSKz0VnpV4e+Mj0w8LQKeidu0jQHj+Oh2 c9Ow== Received: from ?IPv6:2620:10d:c0a3:1407:b1e3:4b44:a67c:b856? ([2620:10d:c091:500::1:e068]) by smtp.googlemail.com with ESMTPSA id f11sm13062462pjg.1.2019.05.31.06.23.41 (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Fri, 31 May 2019 06:23:41 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++PATCH] Lambda names are anonymous Message-ID: <36bb0af3-dbf1-b881-3f5f-9083f8755be5@acm.org> Date: Fri, 31 May 2019 09:23:39 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 Lambda types have names that are anonymous for all intents and purposes, but sometimes need to be distinguished from other unnamed types. We currently create lambda names specially. This patch changes that to use the anon-name machinery, and then set another spare bit on that identifier to mark it specially. The 'LAMBDA_TYPE_P' macro can accept any node (not just types), but that (a) is different to the TYPE_ANON_P and other such macros, and (b) nearly all use cases fall into: i) we know we have a type, ii) we're doing LAMBDA_TYPE_P (DECL_CONTEXT (thing)) This suggests replacing LAMBDA_TYPE_P with: 1) TYPE_LAMBDA_P for cases we have a type 2) DECL_LAMBDA_SCOPE_P for the context case (mirroring DECL_CLASS_SCOPE_P) I'll do that in a later patch. nathan 2019-05-31 Nathan Sidwell * cp-tree.h (IDENTIFIER_LAMBDA_P): New. (TYPE_ANON_P): New. (LAMBDA_TYPE_P, TYPE_UNNAMED_P): Likewise. (LAMBDANAME_PREFIX, LAMBDANAME_FORMAT): Delete. (make_lambda_name): Don't declare. * error.c (dump_aggr_type): Check for lambdas before other anonymous names. * lambda.c (begin_lambda_type): Use make_anon_name. * cp-lang.c (cxx_dwarf_name): Lambda names smell anonymous. * mangle.c (write_local_name): Likewise. * name-lookup.c (lambda_cnt, make_lambda_name): Delete. Index: gcc/cp/cp-lang.c =================================================================== --- gcc/cp/cp-lang.c (revision 271809) +++ gcc/cp/cp-lang.c (working copy) @@ -110,6 +110,5 @@ cxx_dwarf_name (tree t, int verbosity) gcc_assert (DECL_P (t)); - if (DECL_NAME (t) - && (IDENTIFIER_ANON_P (DECL_NAME (t)) || LAMBDA_TYPE_P (t))) + if (DECL_NAME (t) && IDENTIFIER_ANON_P (DECL_NAME (t))) return NULL; if (verbosity >= 2) Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 271809) +++ gcc/cp/cp-tree.h (working copy) @@ -1298,7 +1298,14 @@ struct GTY (()) tree_trait_expr { }; +/* Identifiers used for lambda types are almost anonymous. Use this + spare flag to distinguish them (they also have the anonymous flag). */ +#define IDENTIFIER_LAMBDA_P(NODE) \ + (IDENTIFIER_NODE_CHECK(NODE)->base.protected_flag) + /* Based off of TYPE_UNNAMED_P. */ -#define LAMBDA_TYPE_P(NODE) \ - (CLASS_TYPE_P (NODE) && CLASSTYPE_LAMBDA_EXPR (NODE)) +#define LAMBDA_TYPE_P(NODE) \ + (TREE_CODE (NODE) == RECORD_TYPE \ + && TYPE_LINKAGE_IDENTIFIER (NODE) \ + && IDENTIFIER_LAMBDA_P (TYPE_LINKAGE_IDENTIFIER (NODE))) /* Test if FUNCTION_DECL is a lambda function. */ @@ -1936,7 +1943,13 @@ enum languages { lang_c, lang_cplusplus #define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE))) -/* Nonzero if NODE has no name for linkage purposes. */ -#define TYPE_UNNAMED_P(NODE) \ - (OVERLOAD_TYPE_P (NODE) && IDENTIFIER_ANON_P (TYPE_LINKAGE_IDENTIFIER (NODE))) +/* Any kind of anonymous type. */ +#define TYPE_ANON_P(NODE) \ + (TYPE_LINKAGE_IDENTIFIER (NODE) \ + && IDENTIFIER_ANON_P (TYPE_LINKAGE_IDENTIFIER (NODE))) + +/* Nonzero if NODE, a TYPE, has no name for linkage purposes. */ +#define TYPE_UNNAMED_P(NODE) \ + (TYPE_ANON_P (NODE) \ + && !IDENTIFIER_LAMBDA_P (TYPE_LINKAGE_IDENTIFIER (NODE))) /* The _DECL for this _TYPE. */ @@ -5358,7 +5371,4 @@ extern GTY(()) vec *keyed_c #endif /* NO_DOT_IN_LABEL */ -#define LAMBDANAME_PREFIX "__lambda" -#define LAMBDANAME_FORMAT LAMBDANAME_PREFIX "%d" - #define UDLIT_OP_ANSI_PREFIX "operator\"\"" #define UDLIT_OP_ANSI_FORMAT UDLIT_OP_ANSI_PREFIX "%s" @@ -6366,5 +6376,4 @@ extern bool note_iteration_stmt_body_sta extern void note_iteration_stmt_body_end (bool); extern void determine_local_discriminator (tree); -extern tree make_lambda_name (void); extern int decls_match (tree, tree, bool = true); extern bool maybe_version_functions (tree, tree, bool); Index: gcc/cp/error.c =================================================================== --- gcc/cp/error.c (revision 271809) +++ gcc/cp/error.c (working copy) @@ -739,12 +739,5 @@ dump_aggr_type (cxx_pretty_printer *pp, } - if (!name || IDENTIFIER_ANON_P (name)) - { - if (flags & TFF_CLASS_KEY_OR_ENUM) - pp_string (pp, M_("")); - else - pp_printf (pp, M_(""), variety); - } - else if (LAMBDA_TYPE_P (t)) + if (LAMBDA_TYPE_P (t)) { /* A lambda's "type" is essentially its signature. */ @@ -756,6 +749,14 @@ dump_aggr_type (cxx_pretty_printer *pp, pp_greater (pp); } + else if (!name || IDENTIFIER_ANON_P (name)) + { + if (flags & TFF_CLASS_KEY_OR_ENUM) + pp_string (pp, M_("")); + else + pp_printf (pp, M_(""), variety); + } else pp_cxx_tree_identifier (pp, name); + if (tmplate) dump_template_parms (pp, TYPE_TEMPLATE_INFO (t), Index: gcc/cp/lambda.c =================================================================== --- gcc/cp/lambda.c (revision 271809) +++ gcc/cp/lambda.c (working copy) @@ -129,20 +129,13 @@ tree begin_lambda_type (tree lambda) { - tree type; + /* Lambda names are nearly but not quite anonymous. */ + tree name = make_anon_name (); + IDENTIFIER_LAMBDA_P (name) = true; - { - /* Unique name. This is just like an unnamed class, but we cannot use - make_anon_name because of certain checks against TYPE_UNNAMED_P. */ - tree name; - name = make_lambda_name (); - - /* Create the new RECORD_TYPE for this lambda. */ - type = xref_tag (/*tag_code=*/record_type, - name, - /*scope=*/ts_lambda, - /*template_header_p=*/false); - if (type == error_mark_node) - return error_mark_node; - } + /* Create the new RECORD_TYPE for this lambda. */ + tree type = xref_tag (/*tag_code=*/record_type, name, + /*scope=*/ts_lambda, /*template_header_p=*/false); + if (type == error_mark_node) + return error_mark_node; /* Designate it as a struct so that we can use aggregate initialization. */ Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 271809) +++ gcc/cp/mangle.c (working copy) @@ -2005,6 +2005,5 @@ write_local_name (tree function, const t if (DECL_DISCRIMINATOR_P (local_entity) && !(TREE_CODE (local_entity) == TYPE_DECL - && (LAMBDA_TYPE_P (TREE_TYPE (local_entity)) - || TYPE_UNNAMED_P (TREE_TYPE (local_entity))))) + && TYPE_ANON_P (TREE_TYPE (local_entity)))) write_discriminator (discriminator_for_local_entity (local_entity)); } Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 271809) +++ gcc/cp/name-lookup.c (working copy) @@ -3798,20 +3798,4 @@ constructor_name_p (tree name, tree type } -/* 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; - -tree -make_lambda_name (void) -{ - char buf[32]; - - sprintf (buf, LAMBDANAME_FORMAT, lambda_cnt++); - return get_identifier (buf); -} - /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the caller to set DECL_CONTEXT properly.