aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2022-10-31 06:11:28 -0400
committerNathan Sidwell <nathan@acm.org>2022-11-01 06:04:48 -0400
commit0122faae30fe1ad1dfa8c69f3d3f0428b996b600 (patch)
treeb22a5db786c232d8636ce81e8898afc4a66c7340 /gcc/cp/pt.cc
parent4acc4c2be84d66075d60736623c3a7134d129eaa (diff)
downloadgcc-0122faae30fe1ad1dfa8c69f3d3f0428b996b600.zip
gcc-0122faae30fe1ad1dfa8c69f3d3f0428b996b600.tar.gz
gcc-0122faae30fe1ad1dfa8c69f3d3f0428b996b600.tar.bz2
c++: Reorganize per-scope lambda discriminators
We currently use a per-extra-scope counter to discriminate multiple lambdas in a particular such scope. This is not ABI compliant. This patch merely refactors the existing code to make it easier to drop in a conformant mangling -- there's no functional change here. I rename the LAMBDA_EXPR_DISCIMINATOR to LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR, foreshadowing that there'll be a new discriminator. To provide ABI warnings we'll need to calculate both, and that requires some repacking of the lambda_expr's fields. Finally, although we end up calling the discriminator setter and the scope recorder (nearly) always consecutively, it's clearer to handle it as two separate operations. That also allows us to remove the instantiation special-case for a null extra-scope. gcc/cp/ * cp-tree.h (LAMBDA_EXPR_DISCRIMINATOR): Rename to ... (LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR): ... here. (struct tree_lambda_expr): Make default_capture_mode & discriminator_scope bitfields. (record_null_lambda_scope) Delete. (record_lambda_scope_discriminator): Declare. * lambda.cc (struct lambda_discriminator): New struct. (lambda_scope, lambda_scope_stack): Adjust types. (lambda_count): Delete. (struct tree_int): Delete. (start_lambda_scope, finish_lambda_scope): Adjust. (record_lambda_scope): Only record the scope. (record_lambda_scope_discriminator): New. * mangle.cc (write_closure_type_name): Adjust. * module.cc (trees_out::core_vals): Likewise, (trees_in::core_vals): Likewise. * parser.cc (cp_parser_lambda_expression): Call record_lambda_scope_discriminator. * pt.cc (tsubst_lambda_expr): Adjust record_lambda_scope caling. Call record_lambda_scope_discriminator. Commonize control flow on tsubsting the operator function. libcc1/ * libcp1plugin.cc (plugin_start_closure): Adjust. gcc/testsuite/ * g++.dg/abi/lambda-sig1-17.C: New. * g++.dg/abi/lambda-sig1.h: New. * g++.dg/cpp1y/lambda-mangle-1.C: Extracted to ... * g++.dg/cpp1y/lambda-mangle-1.h: ... here. * g++.dg/cpp1y/lambda-mangle-1-11.C: New * g++.dg/cpp1y/lambda-mangle-1-17.C
Diffstat (limited to 'gcc/cp/pt.cc')
-rw-r--r--gcc/cp/pt.cc50
1 files changed, 15 insertions, 35 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 51bfbbc..fc6279c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -19866,21 +19866,13 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (type == error_mark_node)
return error_mark_node;
- if (LAMBDA_EXPR_EXTRA_SCOPE (t) == NULL_TREE)
- {
- /* A lambda in a default argument outside a class gets no
- LAMBDA_EXPR_EXTRA_SCOPE, as specified by the ABI. But
- tsubst_default_argument calls start_lambda_scope, so we need to
- specifically ignore it here, and use the global scope. */
- record_null_lambda_scope (r);
-
- /* If we're pushed into another scope (PR105652), fix it. */
- if (TYPE_NAMESPACE_SCOPE_P (TREE_TYPE (t)))
- TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type))
- = TYPE_CONTEXT (TREE_TYPE (t));
- }
- else
+ if (LAMBDA_EXPR_EXTRA_SCOPE (t))
record_lambda_scope (r);
+ else if (TYPE_NAMESPACE_SCOPE_P (TREE_TYPE (t)))
+ /* If we're pushed into another scope (PR105652), fix it. */
+ TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type))
+ = TYPE_CONTEXT (TREE_TYPE (t));
+ record_lambda_scope_discriminator (r);
/* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
determine_visibility (TYPE_NAME (type));
@@ -19911,29 +19903,17 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
fntype = build_memfn_type (fntype, type,
type_memfn_quals (fntype),
type_memfn_rqual (fntype));
- tree fn, tmpl;
- if (oldtmpl)
+ tree inst = (oldtmpl
+ ? tsubst_template_decl (oldtmpl, args, complain, fntype)
+ : tsubst_function_decl (oldfn, args, complain, fntype));
+ if (inst == error_mark_node)
{
- tmpl = tsubst_template_decl (oldtmpl, args, complain, fntype);
- if (tmpl == error_mark_node)
- {
- r = error_mark_node;
- goto out;
- }
- fn = DECL_TEMPLATE_RESULT (tmpl);
- finish_member_declaration (tmpl);
- }
- else
- {
- tmpl = NULL_TREE;
- fn = tsubst_function_decl (oldfn, args, complain, fntype);
- if (fn == error_mark_node)
- {
- r = error_mark_node;
- goto out;
- }
- finish_member_declaration (fn);
+ r = error_mark_node;
+ goto out;
}
+ finish_member_declaration (inst);
+
+ tree fn = oldtmpl ? DECL_TEMPLATE_RESULT (inst) : inst;
/* Let finish_function set this. */
DECL_DECLARED_CONSTEXPR_P (fn) = false;