public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++PATCH] Lambda names are anonymous
@ 2019-05-31 13:43 Nathan Sidwell
  0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2019-05-31 13:43 UTC (permalink / raw)
  To: GCC Patches

[-- 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.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-05-31 13:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-31 13:43 [C++PATCH] Lambda names are anonymous Nathan Sidwell

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).