c++: per-scope, per-signature lambda discriminators
authorNathan Sidwell <nathan@acm.org>
Mon, 31 Oct 2022 10:11:28 +0000 (06:11 -0400)
committerNathan Sidwell <nathan@acm.org>
Tue, 1 Nov 2022 21:44:36 +0000 (17:44 -0400)
commit2b0e81d5cc2f7e1d773f6c502bd65b097f392675
tree56bc63afdde5a1c5b0aef088a4dafdcb200c08c0
parent4f8aac77e05d0ae0b7f242fd1aa344d36ff52ceb
c++: per-scope, per-signature lambda discriminators

This implements ABI-compliant lambda discriminators.  Not only do we
have per-scope counters, but we also distinguish by lambda signature.
Only lambdas with the same signature will need non-zero
discriminators.  As the discriminator is signature-dependent, we have
to process the lambda function's declaration before we can determine
it.  For templated and generic lambdas the signature is that of the
uninstantiated lambda -- not separate for each instantiation.

With this change, gcc and clang now produce the same lambda manglings
for all these testcases.

gcc/cp/
* cp-tree.h (LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR): New.
(struct tree_lambda_expr): Add discriminator_sig bitfield.
(recrd_lambda_scope_sig_discriminator): Declare.
* lambda.cc (struct lambda_sig_count): New.
(lambda_discriminator): Add signature vector.
(start_lambda_scope): Adjust.
(compare_lambda_template_head, compare_lambda_sig): New.
(record_lambda_scope_sig_discriminator): New.
* mangle.cc (write_closure_type): Use the scope-sig discriminator for
ABI >= 18.  Emit abi mangling warning if needed.
* module.cc (trees_out::core_vals): Stream the new discriminator.
(trees_in::core_vals): Likewise.
* parser.cc (cp_parser_lambda_declarator_opt): Call
record_lambda_scope_sig_discriminator.
* pt.cc (tsubst_lambda_expr): Likewise.
libcc1/
* libcp1plugin.cc (plugin_start_lambda_closure_class_type):
Initialize the per-scope, per-signature discriminator.
gcc/testsuite/
* g++.dg/abi/lambda-sig1-18.C: New.
* g++.dg/abi/lambda-sig1-18vs17.C: New.
* g++.dg/cpp1y/lambda-mangle-1-18.C: New.
gcc/cp/cp-tree.h
gcc/cp/lambda.cc
gcc/cp/mangle.cc
gcc/cp/module.cc
gcc/cp/parser.cc
gcc/cp/pt.cc
gcc/testsuite/g++.dg/abi/lambda-sig1-18.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C [new file with mode: 0644]
libcc1/libcp1plugin.cc