[C++PATCH] Lambda names are anonymous
authorNathan Sidwell <nathan@acm.org>
Fri, 31 May 2019 13:25:46 +0000 (13:25 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Fri, 31 May 2019 13:25:46 +0000 (13:25 +0000)
https://gcc.gnu.org/ml/gcc-patches/2019-05/msg02126.html
* 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.

From-SVN: r271811

gcc/cp/ChangeLog
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/error.c
gcc/cp/lambda.c
gcc/cp/mangle.c
gcc/cp/name-lookup.c

index ae3db6f..d05719b 100644 (file)
@@ -1,3 +1,17 @@
+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.
+
 2019-05-30  Marek Polacek  <polacek@redhat.com>
 
        * cp-tree.h (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): Fix a typo.
index b725dec..be34871 100644 (file)
@@ -109,8 +109,7 @@ 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)
     return decl_as_dwarf_string (t,
index edd59d5..4d79c43 100644 (file)
@@ -1297,9 +1297,16 @@ struct GTY (()) tree_trait_expr {
   enum cp_trait_kind kind;
 };
 
+/* 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.  */
 #define LAMBDA_FUNCTION_P(FNDECL)                              \
@@ -1935,9 +1942,15 @@ enum languages { lang_c, lang_cplusplus };
 #define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE)))
 #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.  */
 #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
@@ -5357,9 +5370,6 @@ extern GTY(()) vec<tree, va_gc> *keyed_classes;
 #endif /* NO_DOLLAR_IN_LABEL */
 #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"
 #define UDLIT_OP_MANGLED_PREFIX "li"
@@ -6365,7 +6375,6 @@ extern void note_break_stmt                       (void);
 extern bool note_iteration_stmt_body_start     (void);
 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);
 extern tree duplicate_decls                    (tree, tree, bool);
index 5e7c36d..d94f5a3 100644 (file)
@@ -738,14 +738,7 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
       name = DECL_NAME (name);
     }
 
-  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.  */
       pp_string (pp, M_("<lambda"));
@@ -755,8 +748,16 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
                         flags);
       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),
                         !CLASSTYPE_USE_TEMPLATE (t),
index fb385c6..758773b 100644 (file)
@@ -128,22 +128,15 @@ build_lambda_object (tree lambda_expr)
 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.  */
   CLASSTYPE_DECLARED_CLASS (type) = false;
index d66482b..4d6f580 100644 (file)
@@ -2004,8 +2004,7 @@ write_local_name (tree function, const tree local_entity,
       write_name (entity, /*ignore_local_scope=*/1);
       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 242e30f..0bea41f 100644 (file)
@@ -3797,22 +3797,6 @@ constructor_name_p (tree name, tree type)
   return false;
 }
 
-/* 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.