Commit ca3edeae by Nathan Sidwell Committed by Nathan Sidwell

[C++PATCH] Lambda names are anonymous

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
parent 929c046d
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> 2019-05-30 Marek Polacek <polacek@redhat.com>
* cp-tree.h (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): Fix a typo. * cp-tree.h (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): Fix a typo.
......
...@@ -109,8 +109,7 @@ cxx_dwarf_name (tree t, int verbosity) ...@@ -109,8 +109,7 @@ cxx_dwarf_name (tree t, int verbosity)
{ {
gcc_assert (DECL_P (t)); gcc_assert (DECL_P (t));
if (DECL_NAME (t) if (DECL_NAME (t) && IDENTIFIER_ANON_P (DECL_NAME (t)))
&& (IDENTIFIER_ANON_P (DECL_NAME (t)) || LAMBDA_TYPE_P (t)))
return NULL; return NULL;
if (verbosity >= 2) if (verbosity >= 2)
return decl_as_dwarf_string (t, return decl_as_dwarf_string (t,
......
...@@ -1297,9 +1297,16 @@ struct GTY (()) tree_trait_expr { ...@@ -1297,9 +1297,16 @@ struct GTY (()) tree_trait_expr {
enum cp_trait_kind kind; 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. */ /* Based off of TYPE_UNNAMED_P. */
#define LAMBDA_TYPE_P(NODE) \ #define LAMBDA_TYPE_P(NODE) \
(CLASS_TYPE_P (NODE) && CLASSTYPE_LAMBDA_EXPR (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. */ /* Test if FUNCTION_DECL is a lambda function. */
#define LAMBDA_FUNCTION_P(FNDECL) \ #define LAMBDA_FUNCTION_P(FNDECL) \
...@@ -1935,9 +1942,15 @@ enum languages { lang_c, lang_cplusplus }; ...@@ -1935,9 +1942,15 @@ enum languages { lang_c, lang_cplusplus };
#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE))) #define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE)))
#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE))) #define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE)))
/* Nonzero if NODE has no name for linkage purposes. */ /* Any kind of anonymous type. */
#define TYPE_UNNAMED_P(NODE) \ #define TYPE_ANON_P(NODE) \
(OVERLOAD_TYPE_P (NODE) && IDENTIFIER_ANON_P (TYPE_LINKAGE_IDENTIFIER (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. */ /* The _DECL for this _TYPE. */
#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
...@@ -5357,9 +5370,6 @@ extern GTY(()) vec<tree, va_gc> *keyed_classes; ...@@ -5357,9 +5370,6 @@ extern GTY(()) vec<tree, va_gc> *keyed_classes;
#endif /* NO_DOLLAR_IN_LABEL */ #endif /* NO_DOLLAR_IN_LABEL */
#endif /* NO_DOT_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_PREFIX "operator\"\""
#define UDLIT_OP_ANSI_FORMAT UDLIT_OP_ANSI_PREFIX "%s" #define UDLIT_OP_ANSI_FORMAT UDLIT_OP_ANSI_PREFIX "%s"
#define UDLIT_OP_MANGLED_PREFIX "li" #define UDLIT_OP_MANGLED_PREFIX "li"
...@@ -6365,7 +6375,6 @@ extern void note_break_stmt (void); ...@@ -6365,7 +6375,6 @@ extern void note_break_stmt (void);
extern bool note_iteration_stmt_body_start (void); extern bool note_iteration_stmt_body_start (void);
extern void note_iteration_stmt_body_end (bool); extern void note_iteration_stmt_body_end (bool);
extern void determine_local_discriminator (tree); extern void determine_local_discriminator (tree);
extern tree make_lambda_name (void);
extern int decls_match (tree, tree, bool = true); extern int decls_match (tree, tree, bool = true);
extern bool maybe_version_functions (tree, tree, bool); extern bool maybe_version_functions (tree, tree, bool);
extern tree duplicate_decls (tree, tree, bool); extern tree duplicate_decls (tree, tree, bool);
......
...@@ -738,14 +738,7 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags) ...@@ -738,14 +738,7 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
name = DECL_NAME (name); name = DECL_NAME (name);
} }
if (!name || IDENTIFIER_ANON_P (name)) if (LAMBDA_TYPE_P (t))
{
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))
{ {
/* A lambda's "type" is essentially its signature. */ /* A lambda's "type" is essentially its signature. */
pp_string (pp, M_("<lambda")); pp_string (pp, M_("<lambda"));
...@@ -755,8 +748,16 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags) ...@@ -755,8 +748,16 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
flags); flags);
pp_greater (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 else
pp_cxx_tree_identifier (pp, name); pp_cxx_tree_identifier (pp, name);
if (tmplate) if (tmplate)
dump_template_parms (pp, TYPE_TEMPLATE_INFO (t), dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
!CLASSTYPE_USE_TEMPLATE (t), !CLASSTYPE_USE_TEMPLATE (t),
......
...@@ -128,22 +128,15 @@ build_lambda_object (tree lambda_expr) ...@@ -128,22 +128,15 @@ build_lambda_object (tree lambda_expr)
tree tree
begin_lambda_type (tree lambda) 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;
{ /* Create the new RECORD_TYPE for this lambda. */
/* Unique name. This is just like an unnamed class, but we cannot use tree type = xref_tag (/*tag_code=*/record_type, name,
make_anon_name because of certain checks against TYPE_UNNAMED_P. */ /*scope=*/ts_lambda, /*template_header_p=*/false);
tree name; if (type == error_mark_node)
name = make_lambda_name (); return error_mark_node;
/* 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;
}
/* Designate it as a struct so that we can use aggregate initialization. */ /* Designate it as a struct so that we can use aggregate initialization. */
CLASSTYPE_DECLARED_CLASS (type) = false; CLASSTYPE_DECLARED_CLASS (type) = false;
......
...@@ -2004,8 +2004,7 @@ write_local_name (tree function, const tree local_entity, ...@@ -2004,8 +2004,7 @@ write_local_name (tree function, const tree local_entity,
write_name (entity, /*ignore_local_scope=*/1); write_name (entity, /*ignore_local_scope=*/1);
if (DECL_DISCRIMINATOR_P (local_entity) if (DECL_DISCRIMINATOR_P (local_entity)
&& !(TREE_CODE (local_entity) == TYPE_DECL && !(TREE_CODE (local_entity) == TYPE_DECL
&& (LAMBDA_TYPE_P (TREE_TYPE (local_entity)) && TYPE_ANON_P (TREE_TYPE (local_entity))))
|| TYPE_UNNAMED_P (TREE_TYPE (local_entity)))))
write_discriminator (discriminator_for_local_entity (local_entity)); write_discriminator (discriminator_for_local_entity (local_entity));
} }
} }
......
...@@ -3797,22 +3797,6 @@ constructor_name_p (tree name, tree type) ...@@ -3797,22 +3797,6 @@ constructor_name_p (tree name, tree type)
return false; 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 /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the
caller to set DECL_CONTEXT properly. caller to set DECL_CONTEXT properly.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment