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.
===================================================================
@@ -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)
===================================================================
@@ -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);
===================================================================
@@ -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),
===================================================================
@@ -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. */
===================================================================
@@ -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));
}
===================================================================
@@ -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.