From ca3edeaed691cf971ebdf7768f5d73b182c1aa07 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 31 May 2019 13:25:46 +0000 Subject: [PATCH] [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 --- gcc/cp/ChangeLog | 14 ++++++++++++++ gcc/cp/cp-lang.c | 3 +-- gcc/cp/cp-tree.h | 27 ++++++++++++++++++--------- gcc/cp/error.c | 17 +++++++++-------- gcc/cp/lambda.c | 23 ++++++++--------------- gcc/cp/mangle.c | 3 +-- gcc/cp/name-lookup.c | 16 ---------------- 7 files changed, 51 insertions(+), 52 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ae3db6f0460..d05719b9bbe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2019-05-31 Nathan Sidwell + + * 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 * 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 b725dece4bb..be34871dd08 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 edd59d5f000..4d79c43c5af 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 *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 5e7c36d8698..d94f5a3b667 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_("")); - else - pp_printf (pp, M_(""), variety); - } - else if (LAMBDA_TYPE_P (t)) + if (LAMBDA_TYPE_P (t)) { /* A lambda's "type" is essentially its signature. */ pp_string (pp, M_("")); + else + pp_printf (pp, M_(""), 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 fb385c62687..758773b8a85 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 d66482b194d..4d6f58093c1 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 242e30f8a12..0bea41ffb91 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. -- 2.30.2