aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2019-05-31 13:25:46 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2019-05-31 13:25:46 +0000
commitca3edeaed691cf971ebdf7768f5d73b182c1aa07 (patch)
tree70d2c9af2fdf1addd53538a38013476747599eca
parent929c046d575c273e80000310b88c24af94cc4cf8 (diff)
downloadgcc-ca3edeaed691cf971ebdf7768f5d73b182c1aa07.zip
gcc-ca3edeaed691cf971ebdf7768f5d73b182c1aa07.tar.gz
gcc-ca3edeaed691cf971ebdf7768f5d73b182c1aa07.tar.bz2
[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
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/cp-lang.c3
-rw-r--r--gcc/cp/cp-tree.h27
-rw-r--r--gcc/cp/error.c17
-rw-r--r--gcc/cp/lambda.c23
-rw-r--r--gcc/cp/mangle.c3
-rw-r--r--gcc/cp/name-lookup.c16
7 files changed, 51 insertions, 52 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ae3db6f..d05719b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index b725dec..be34871 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -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,
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index edd59d5..4d79c43 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 5e7c36d..d94f5a3 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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),
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index fb385c6..758773b 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -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;
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index d66482b..4d6f580 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -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));
}
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 242e30f..0bea41f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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.