public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Nathan Sidwell <nathan@acm.org>
To: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: [C++PATCH] Lambda names are anonymous
Date: Fri, 31 May 2019 13:43:00 -0000	[thread overview]
Message-ID: <36bb0af3-dbf1-b881-3f5f-9083f8755be5@acm.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 793 bytes --]

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

-- 
Nathan Sidwell

[-- Attachment #2: lambda-name.diff --]
[-- Type: text/x-patch, Size: 6601 bytes --]

2019-05-31  Nathan Sidwell  <nathan@acm.org>

	* 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<tree, va_gc> *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_("<unnamed>"));
-      else
-	pp_printf (pp, M_("<unnamed %s>"), 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_("<unnamed>"));
+      else
+	pp_printf (pp, M_("<unnamed %s>"), 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.

                 reply	other threads:[~2019-05-31 13:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=36bb0af3-dbf1-b881-3f5f-9083f8755be5@acm.org \
    --to=nathan@acm.org \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).