-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fully specify the mangling of non-type template arguments #166
base: main
Are you sure you want to change the base?
Conversation
Mostly includes content from itanium-cxx-abi#63
This includes the material from itanium-cxx-abi#47 (non-type template arguments), itanium-cxx-abi#63 (class constants), and the template-param-decl portions of itanium-cxx-abi#85 (C++20 lambda-expressions). @zygoloid gets credit for most of this, although I've made a few substantive changes from his suggestions.
type. | ||
|
||
<p> | ||
Null pointers and member pointers are mangled as as a literal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Null pointers and member pointers are mangled as as a literal | |
Null pointers and member pointers are mangled as a literal |
Non-type template argument values of class type are mangled as | ||
a direct initialization (<code>tl</code>) of the class type | ||
using the <a href="#mangling.member-initializer-sequence">member | ||
initiializer sequence</a> for the contents of the type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initiializer sequence</a> for the contents of the type. | |
initializer sequence</a> for the contents of the type. |
field and class names into the ABI. If the offset is zero, it can | ||
be omitted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
field and class names into the ABI. If the offset is zero, it can | |
be omitted. | |
field and class names into the ABI. If the offset is zero, it is | |
omitted. |
A value is converted to a flattened sequence of values by applying | ||
the following expansions until no values of array or non-union class | ||
type remain: | ||
<ul compact> | ||
<li>A value of array type is replaced by its element values in | ||
index order. | ||
<li>A value of non-union class type is replaced by the values | ||
of its base subobjects, in order of declaration, followed | ||
by the values of its non-static data members, in order of | ||
declaration. | ||
</ul> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang and GCC don't do this flattening; this would be an ABI change for both: https://godbolt.org/z/nzWP13MMf ... but I think these manglings are new enough that we can afford to change them.
For the most part, this flattening seems good: it'll make manglings shorter in some cases, and avoids encoding details of the internal structure of the type (eg, empty base classes and additional layers of base class wrapping don't affect the mangling). But it also will cause problems for the tail-dropping below, for the motivating cases such as:
struct StringParam {
char data[256];
int length;
};
template<StringParam str> void f();
... where the rule used by Clang and GCC would mangle f<{"foo", 3}>()
relatively compactly (_Z1fIXtl11StringParamtlA256_cLc102ELc111ELc111EELi3EEEEvv
) but this flattening will mean that we can't do the tail-dropping any more and will encode 253 additional zero Lc0E
s before the Li3E
.
Perhaps we can keep the flattening of non-union class types and remove the flattening of arrays? Because we don't need precise typing, we can use il
instead of tl
here, rather than encoding the array type as Clang and GCC currently do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not flattening arrays so that we can use tail optimization makes sense to me; I can write that up.
|
||
<p> | ||
Non-type template argument values of class type are mangled as | ||
a direct initialization (<code>tl</code>) of the class type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use il
instead of tl <type>
when precise typing is not required. This would make a difference when mangling a union member that is itself of class type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be a total break with the provisional manglings implementations have been using for class template arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I suppose this would change all manglings for (eg) class templates with non-type parameters of class type. That said, the addition of flattening is a pretty big change too. How big a break are we prepared to accept here? Unlike some of the other manglings we're changing in this PR, these ones only affect C++20 onwards.
Something that came up in discussion on #111: what should we do with array-to-pointer decay, in the case where a precise type is not needed? This has been valid since C++98, as an exception to the old general rule that a pointer template parameter couldn't point to a subobject. For example:
GCC mangles this as |
Thanks for preparing this! I have some questions inline. |
@@ -4533,13 +4533,13 @@ <h5><a href="#mangling.dependent">Dependent constructs in templates</a></h5> | |||
<h5><a href="#mangling.anonymous">Anonymous entities</a></h5> | |||
|
|||
<p> | |||
For the purposes of mangling, the name of an anonymous union is | |||
considered to be the name of the first named data member found by a | |||
For the purposes of mangling, the name of an anonymous struct or union |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anonymous structs are a part of the C language standard but not of the C++ standard currently, AFAIK. Is the suggested change for compiler extensions?
@@ -5526,16 +5524,148 @@ <h5><a href="#mangle.template-arg">5.1.5.10 Template Arguments</a></h5> | |||
::= X <<a href="#mangle.expression">expression</a>> E # expression | |||
::= <<a href="#mangle.expr-primary">expr-primary</a>> # simple expressions | |||
::= J <<a href="#mangle.template-arg">template-arg</a>>* E # argument pack | |||
::= <<a href="#mangle.template-param-decl">template-param-decl</a>> <<a href="#mangle.template-arg">template-arg</a>> # converted template argument |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-uniform indentation of the comment.
<p> | ||
Next, if the constant is a pointer, the reference expression is | ||
wrapped in a unary <code>&</code> operator (that is, prefixed with | ||
<code class=mangle>ad</code>. The notional type of this expression |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<code class=mangle>ad</code>. The notional type of this expression | |
<code class=mangle>ad</code>). The notional type of this expression |
struct C : A, B {}; | ||
template <void (C::*)()> void f(); | ||
|
||
f<&A::foo> // _Z1fIXmcM1CFvvEadL_ZN1A3fooEvE1EEEvv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should mc
mangling contain class type or pointer-to-member type, as in this example?
if the class is a union, to at most one non-static data member, | ||
called the active union member. Under the standard, this exact | ||
structure uniquely determines a value, including whether a union | ||
has an active union member member and (if so) which one. As |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has an active union member member and (if so) which one. As | |
has an active union member and (if so) which one. As |
|
||
C<0,0> // 1CIXtl1BEEE | ||
C<1,0> // 1CIXtl1BtlNS0_Ut_Edi1atl1ALi1EEEEEE | ||
C<1,1> // 1CIXtl1BtlNS0_Ut_Edi1atl1ALi1ELi1EEEEEE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you lost curly braces in template arguments?
same template head; | ||
<li>the argument is a type and the parameter is unconstrained; or | ||
<li>the argument is a non-type template argument and the declared | ||
parameter type neither is instantiation dependent nor contains |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it intended to change the mangling of C++98 code like
template <class T, T V> T f() { return V; }
int main() { return f<int,42>(); }
? Most of the templates I see that use <typename T, T V>
are classes and so unaffected, but there's at least one internal helper function in libstdc++ that will be changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Saying that only a type parameter pack can be natural for an empty argument pack also changes the mangling of C++11 code like
template <int i> int max() { return i; }
template <int i, int j, int... rest> int max()
{
int sub = max<j, rest...>();
return i > sub ? i : sub;
}
int main() { return max<1,2,3>(); }
and requiring template template args to have the same template head changes the mangling of C++11 code like
template <template <typename...> class TT, typename... Ts> TT<Ts...> f();
template <typename> struct A { };
int main() { f<A,int>(); }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some mangling changes for function templates are unavoidable, yeah. Even in C++98, we have the conflict:
// _Z3fooIiLi0EEvv
template <class T, T N> void foo() {}
template void foo<int, 0>();
// _Z3fooIiLi0EEvv
template <class T, int N> void foo() {}
template void foo<int, 0>();
You can't have these both in the same translation unit, but they're formally different templates and need to be mangled differently.
Per itanium-cxx-abi/cxx-abi#24 and itanium-cxx-abi/cxx-abi#166 We need to mangle constraints to be able to distinguish between function templates that only differ in constraints. From the latter link, we want to use the template parameter mangling previously specified for lambdas to also make explicit the form of a template parameter where the argument is not a "natural" fit for it, such as when the parameter is constrained or deduced. I'm concerned about how the latter link changes the mangling for some C++98 and C++11 patterns, so I've limited template_parm_natural_p to avoid two cases found by running the testsuite with -Wabi forced on: template <class T, T V> T f() { return V; } int main() { return f<int,42>(); } template <int i> int max() { return i; } template <int i, int j, int... rest> int max() { int sub = max<j, rest...>(); return i > sub ? i : sub; } int main() { return max<1,2,3>(); } A third C++11 pattern is changed by this patch: template <template <typename...> class TT, typename... Ts> TT<Ts...> f(); template <typename> struct A { }; int main() { f<A,int>(); } I aim to resolve these with the ABI committee before GCC 14.1. We also need to resolve itanium-cxx-abi/cxx-abi#38 (mangling references to dependent template-ids where the name is fully resolved) as references to concepts in std:: will consistently run into this area. This is why mangle-concepts1.C only refers to concepts in the global namespace so far. The library changes are to avoid trying to mangle builtins, which fails. Demangler support and test coverage is not complete yet. gcc/cp/ChangeLog: * cp-tree.h (TEMPLATE_ARGS_TYPE_CONSTRAINT_P): New. (get_concept_check_template): Declare. * constraint.cc (combine_constraint_expressions) (finish_shorthand_constraint): Use UNKNOWN_LOCATION. * pt.cc (convert_generic_types_to_packs): Likewise. * mangle.cc (write_constraint_expression) (write_tparms_constraints, write_type_constraint) (template_parm_natural_p, write_requirement) (write_requires_expr): New. (write_encoding): Mangle trailing requires-clause. (write_name): Pass parms to write_template_args. (write_template_param_decl): Factor out from... (write_closure_template_head): ...here. (write_template_args): Mangle non-natural parms and requires-clause. (write_expression): Handle REQUIRES_EXPR. include/ChangeLog: * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_CONSTRAINTS. libiberty/ChangeLog: * cp-demangle.c (d_make_comp): Handle DEMANGLE_COMPONENT_CONSTRAINTS. (d_count_templates_scopes): Likewise. (d_print_comp_inner): Likewise. (d_maybe_constraints): New. (d_encoding, d_template_args_1): Call it. (d_parmlist): Handle 'Q'. * testsuite/demangle-expected: Add some constraint tests. libstdc++-v3/ChangeLog: * include/std/bit: Avoid builtins in requires-clauses. * include/std/variant: Likewise. gcc/testsuite/ChangeLog: * g++.dg/abi/mangle10.C: Disable compat aliases. * g++.dg/abi/mangle52.C: Specify ABI 18. * g++.dg/cpp2a/class-deduction-alias3.C * g++.dg/cpp2a/class-deduction-alias8.C: Avoid builtins in requires-clauses. * g++.dg/abi/mangle-concepts1.C: New test. * g++.dg/abi/mangle-ttp1.C: New test.
Per itanium-cxx-abi/cxx-abi#24 and itanium-cxx-abi/cxx-abi#166 We need to mangle constraints to be able to distinguish between function templates that only differ in constraints. From the latter link, we want to use the template parameter mangling previously specified for lambdas to also make explicit the form of a template parameter where the argument is not a "natural" fit for it, such as when the parameter is constrained or deduced. I'm concerned about how the latter link changes the mangling for some C++98 and C++11 patterns, so I've limited template_parm_natural_p to avoid two cases found by running the testsuite with -Wabi forced on: template <class T, T V> T f() { return V; } int main() { return f<int,42>(); } template <int i> int max() { return i; } template <int i, int j, int... rest> int max() { int sub = max<j, rest...>(); return i > sub ? i : sub; } int main() { return max<1,2,3>(); } A third C++11 pattern is changed by this patch: template <template <typename...> class TT, typename... Ts> TT<Ts...> f(); template <typename> struct A { }; int main() { f<A,int>(); } I aim to resolve these with the ABI committee before GCC 14.1. We also need to resolve itanium-cxx-abi/cxx-abi#38 (mangling references to dependent template-ids where the name is fully resolved) as references to concepts in std:: will consistently run into this area. This is why mangle-concepts1.C only refers to concepts in the global namespace so far. The library changes are to avoid trying to mangle builtins, which fails. Demangler support and test coverage is not complete yet. gcc/cp/ChangeLog: * cp-tree.h (TEMPLATE_ARGS_TYPE_CONSTRAINT_P): New. (get_concept_check_template): Declare. * constraint.cc (combine_constraint_expressions) (finish_shorthand_constraint): Use UNKNOWN_LOCATION. * pt.cc (convert_generic_types_to_packs): Likewise. * mangle.cc (write_constraint_expression) (write_tparms_constraints, write_type_constraint) (template_parm_natural_p, write_requirement) (write_requires_expr): New. (write_encoding): Mangle trailing requires-clause. (write_name): Pass parms to write_template_args. (write_template_param_decl): Factor out from... (write_closure_template_head): ...here. (write_template_args): Mangle non-natural parms and requires-clause. (write_expression): Handle REQUIRES_EXPR. include/ChangeLog: * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_CONSTRAINTS. libiberty/ChangeLog: * cp-demangle.c (d_make_comp): Handle DEMANGLE_COMPONENT_CONSTRAINTS. (d_count_templates_scopes): Likewise. (d_print_comp_inner): Likewise. (d_maybe_constraints): New. (d_encoding, d_template_args_1): Call it. (d_parmlist): Handle 'Q'. * testsuite/demangle-expected: Add some constraint tests. libstdc++-v3/ChangeLog: * include/std/bit: Avoid builtins in requires-clauses. * include/std/variant: Likewise. gcc/testsuite/ChangeLog: * g++.dg/abi/mangle10.C: Disable compat aliases. * g++.dg/abi/mangle52.C: Specify ABI 18. * g++.dg/cpp2a/class-deduction-alias3.C * g++.dg/cpp2a/class-deduction-alias8.C: Avoid builtins in requires-clauses. * g++.dg/abi/mangle-concepts1.C: New test. * g++.dg/abi/mangle-ttp1.C: New test.
…er gcc versions. This brings in the following commits: commit c73cc6fe6207b2863afa31a3be8ad87b70d3df0a Author: Jakub Jelinek <[email protected]> Date: Tue Dec 5 23:32:19 2023 +0100 libiberty: Fix build with GCC < 7 Tobias reported on IRC that the linker fails to build with GCC 4.8.5. In configure I've tried to use everything actually used in the sha1.c x86 hw implementation, but unfortunately I forgot about implicit function declarations. GCC before 7 did have <cpuid.h> header and bit_SHA define and __get_cpuid function defined inline, but it didn't define __get_cpuid_count, which compiled fine (and the configure test is intentionally compile time only) due to implicit function declaration, but then failed to link when linking the linker, because __get_cpuid_count wasn't defined anywhere. The following patch fixes that by using what autoconf uses in AC_CHECK_DECL to make sure the functions are declared. commit 691858d279335eeeeed3afafdf872b1c5f8f4201 Author: Rainer Orth <[email protected]> Date: Tue Dec 5 11:04:06 2023 +0100 libiberty: Fix pex_unix_wait return type The recent warning patches broke Solaris bootstrap: /vol/gcc/src/hg/master/local/libiberty/pex-unix.c:326:3: error: initialization of 'pid_t (*)(struct pex_obj *, pid_t, int *, struct pex_time *, int, const char **, int *)' {aka 'long int (*)(struct pex_obj *, long int, int *, struct pex_time *, int, const char **, int *)'} from incompatible pointer type 'int (*)(struct pex_obj *, pid_t, int *, struct pex_time *, int, const char **, int *)' {aka 'int (*)(struct pex_obj *, long int, int *, struct pex_time *, int, const char **, int *)'} [-Wincompatible-pointer-types] 326 | pex_unix_wait, | ^~~~~~~~~~~~~ /vol/gcc/src/hg/master/local/libiberty/pex-unix.c:326:3: note: (near initialization for 'funcs.wait') While pex_funcs.wait expects a function returning pid_t, pex_unix_wait currently returns int. However, on Solaris pid_t is long for 32-bit, but int for 64-bit. This patches fixes this by having pex_unix_wait return pid_t as expected, and like every other variant already does. Bootstrapped without regressions on i386-pc-solaris2.11, sparc-sun-solaris2.11, x86_64-pc-linux-gnu, and x86_64-apple-darwin23.1.0. commit c3f281a0c1ca50e4df5049923aa2f5d1c3c39ff6 Author: Jason Merrill <[email protected]> Date: Mon Sep 25 10:15:02 2023 +0100 c++: mangle function template constraints Per itanium-cxx-abi/cxx-abi#24 and itanium-cxx-abi/cxx-abi#166 We need to mangle constraints to be able to distinguish between function templates that only differ in constraints. From the latter link, we want to use the template parameter mangling previously specified for lambdas to also make explicit the form of a template parameter where the argument is not a "natural" fit for it, such as when the parameter is constrained or deduced. I'm concerned about how the latter link changes the mangling for some C++98 and C++11 patterns, so I've limited template_parm_natural_p to avoid two cases found by running the testsuite with -Wabi forced on: template <class T, T V> T f() { return V; } int main() { return f<int,42>(); } template <int i> int max() { return i; } template <int i, int j, int... rest> int max() { int sub = max<j, rest...>(); return i > sub ? i : sub; } int main() { return max<1,2,3>(); } A third C++11 pattern is changed by this patch: template <template <typename...> class TT, typename... Ts> TT<Ts...> f(); template <typename> struct A { }; int main() { f<A,int>(); } I aim to resolve these with the ABI committee before GCC 14.1. We also need to resolve itanium-cxx-abi/cxx-abi#38 (mangling references to dependent template-ids where the name is fully resolved) as references to concepts in std:: will consistently run into this area. This is why mangle-concepts1.C only refers to concepts in the global namespace so far. The library changes are to avoid trying to mangle builtins, which fails. Demangler support and test coverage is not complete yet. commit f2c52c0dfde581461959b0e2b423ad106aadf179 Author: Rainer Orth <[email protected]> Date: Thu Nov 30 10:06:23 2023 +0100 libiberty: Disable hwcaps for sha1.o This patch commit bf4f40cc3195eb7b900bf5535cdba1ee51fdbb8e Author: Jakub Jelinek <[email protected]> Date: Tue Nov 28 13:14:05 2023 +0100 libiberty: Use x86 HW optimized sha1 broke Solaris/x86 bootstrap with the native as: libtool: compile: /var/gcc/regression/master/11.4-gcc/build/./gcc/gccgo -B/var/gcc/regression/master/11.4-gcc/build/./gcc/ -B/vol/gcc/i386-pc-solaris2.11/bin/ -B/vol/gcc/i386-pc-solaris2.11/lib/ -isystem /vol/gcc/i386-pc-solaris2.11/include -isystem /vol/gcc/i386-pc-solaris2.11/sys-include -fchecking=1 -minline-all-stringops -O2 -g -I . -c -fgo-pkgpath=internal/goarch /vol/gcc/src/hg/master/local/libgo/go/internal/goarch/goarch.go zgoarch.go ld.so.1: go1: fatal: /var/gcc/regression/master/11.4-gcc/build/gcc/go1: hardware capability (CA_SUNW_HW_2) unsupported: 0x4000000 [ SHA1 ] gccgo: fatal error: Killed signal terminated program go1 As is already done in a couple of other similar cases, this patches disables hwcaps support for libiberty. Initially, this didn't work because config/hwcaps.m4 uses target_os, but didn't ensure it is defined. Tested on i386-pc-solaris2.11 with as and gas. commit bf4f40cc3195eb7b900bf5535cdba1ee51fdbb8e Author: Jakub Jelinek <[email protected]> Date: Tue Nov 28 13:14:05 2023 +0100 libiberty: Use x86 HW optimized sha1 Nick has approved this patch (+ small ld change to use it for --build-id=), so I'm commiting it to GCC as master as well. If anyone from ARM would be willing to implement it similarly with vsha1{cq,mq,pq,h,su0q,su1q}_u32 intrinsics, it could be a useful linker speedup on those hosts as well, the intent in sha1.c was that sha1_hw_process_bytes, sha1_hw_process_block functions would be defined whenever defined (HAVE_X86_SHA1_HW_SUPPORT) || defined (HAVE_WHATEVERELSE_SHA1_HW_SUPPORT) but the body of sha1_hw_process_block and sha1_choose_process_bytes would then have #elif defined (HAVE_WHATEVERELSE_SHA1_HW_SUPPORT) for the other arch support, similarly for any target attributes on sha1_hw_process_block if needed. commit 01bc30b222a9d2ff0269325d9e367f8f1fcef942 Author: Mark Wielaard <[email protected]> Date: Wed Nov 15 20:27:08 2023 +0100 Regenerate libiberty/aclocal.m4 with aclocal 1.15.1 There is a new buildbot check that all autotool files are generated with the correct versions (automake 1.15.1 and autoconf 2.69). https://builder.sourceware.org/buildbot/#/builders/gcc-autoregen Correct one file that was generated with the wrong version. commit 879cf9ff45d94065d89e24b71c6b27c7076ac518 Author: Brendan Shanks <[email protected]> Date: Thu Nov 9 21:01:07 2023 -0700 [PATCH v3] libiberty: Use posix_spawn in pex-unix when available. Hi, This patch implements pex_unix_exec_child using posix_spawn when available. This should especially benefit recent macOS (where vfork just calls fork), but should have equivalent or faster performance on all platforms. In addition, the implementation is substantially simpler than the vfork+exec code path. Tested on x86_64-linux. v2: Fix error handling (previously the function would be run twice in case of error), and don't use a macro that changes control flow. v3: Match file style for error-handling blocks, don't close in/out/errdes on error, and check close() for errors. commit 810bcc00156cefce7ad40fc9d8de6e43c3a04450 Author: Jason Merrill <[email protected]> Date: Thu Aug 17 11:36:23 2023 -0400 c++: constrained hidden friends [PR109751] r13-4035 avoided a problem with overloading of constrained hidden friends by checking satisfaction, but checking satisfaction early is inconsistent with the usual late checking and can lead to hard errors, so let's not do that after all. We were wrongly treating the different instantiations of the same friend template as the same function because maybe_substitute_reqs_for was failing to actually substitute in the case of a non-template friend. But we don't actually need to do the substitution anyway, because [temp.friend] says that such a friend can't be the same as any other declaration. After fixing that, instead of a redefinition error we got an ambiguous overload error, fixed by allowing constrained hidden friends to coexist until overload resolution, at which point they probably won't be in the same ADL overload set anyway. And we avoid mangling collisions by following the proposed mangling for these friends as a member function with an extra 'F' before the name. I demangle this by just adding [friend] to the name of the function because it's not feasible to reconstruct the actual scope of the function since the mangling ABI doesn't distinguish between class and namespace scopes. PR c++/109751
Per itanium-cxx-abi/cxx-abi#24 and itanium-cxx-abi/cxx-abi#166 We need to mangle constraints to be able to distinguish between function templates that only differ in constraints. From the latter link, we want to use the template parameter mangling previously specified for lambdas to also make explicit the form of a template parameter where the argument is not a "natural" fit for it, such as when the parameter is constrained or deduced. I'm concerned about how the latter link changes the mangling for some C++98 and C++11 patterns, so I've limited template_parm_natural_p to avoid two cases found by running the testsuite with -Wabi forced on: template <class T, T V> T f() { return V; } int main() { return f<int,42>(); } template <int i> int max() { return i; } template <int i, int j, int... rest> int max() { int sub = max<j, rest...>(); return i > sub ? i : sub; } int main() { return max<1,2,3>(); } A third C++11 pattern is changed by this patch: template <template <typename...> class TT, typename... Ts> TT<Ts...> f(); template <typename> struct A { }; int main() { f<A,int>(); } I aim to resolve these with the ABI committee before GCC 14.1. We also need to resolve itanium-cxx-abi/cxx-abi#38 (mangling references to dependent template-ids where the name is fully resolved) as references to concepts in std:: will consistently run into this area. This is why mangle-concepts1.C only refers to concepts in the global namespace so far. The library changes are to avoid trying to mangle builtins, which fails. Demangler support and test coverage is not complete yet. gcc/cp/ChangeLog: * cp-tree.h (TEMPLATE_ARGS_TYPE_CONSTRAINT_P): New. (get_concept_check_template): Declare. * constraint.cc (combine_constraint_expressions) (finish_shorthand_constraint): Use UNKNOWN_LOCATION. * pt.cc (convert_generic_types_to_packs): Likewise. * mangle.cc (write_constraint_expression) (write_tparms_constraints, write_type_constraint) (template_parm_natural_p, write_requirement) (write_requires_expr): New. (write_encoding): Mangle trailing requires-clause. (write_name): Pass parms to write_template_args. (write_template_param_decl): Factor out from... (write_closure_template_head): ...here. (write_template_args): Mangle non-natural parms and requires-clause. (write_expression): Handle REQUIRES_EXPR. include/ChangeLog: * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_CONSTRAINTS. libiberty/ChangeLog: * cp-demangle.c (d_make_comp): Handle DEMANGLE_COMPONENT_CONSTRAINTS. (d_count_templates_scopes): Likewise. (d_print_comp_inner): Likewise. (d_maybe_constraints): New. (d_encoding, d_template_args_1): Call it. (d_parmlist): Handle 'Q'. * testsuite/demangle-expected: Add some constraint tests. libstdc++-v3/ChangeLog: * include/std/bit: Avoid builtins in requires-clauses. * include/std/variant: Likewise. gcc/testsuite/ChangeLog: * g++.dg/abi/mangle10.C: Disable compat aliases. * g++.dg/abi/mangle52.C: Specify ABI 18. * g++.dg/cpp2a/class-deduction-alias3.C * g++.dg/cpp2a/class-deduction-alias8.C: Avoid builtins in requires-clauses. * g++.dg/abi/mangle-concepts1.C: New test. * g++.dg/abi/mangle-ttp1.C: New test.
Per itanium-cxx-abi/cxx-abi#24 and itanium-cxx-abi/cxx-abi#166 We need to mangle constraints to be able to distinguish between function templates that only differ in constraints. From the latter link, we want to use the template parameter mangling previously specified for lambdas to also make explicit the form of a template parameter where the argument is not a "natural" fit for it, such as when the parameter is constrained or deduced. I'm concerned about how the latter link changes the mangling for some C++98 and C++11 patterns, so I've limited template_parm_natural_p to avoid two cases found by running the testsuite with -Wabi forced on: template <class T, T V> T f() { return V; } int main() { return f<int,42>(); } template <int i> int max() { return i; } template <int i, int j, int... rest> int max() { int sub = max<j, rest...>(); return i > sub ? i : sub; } int main() { return max<1,2,3>(); } A third C++11 pattern is changed by this patch: template <template <typename...> class TT, typename... Ts> TT<Ts...> f(); template <typename> struct A { }; int main() { f<A,int>(); } I aim to resolve these with the ABI committee before GCC 14.1. We also need to resolve itanium-cxx-abi/cxx-abi#38 (mangling references to dependent template-ids where the name is fully resolved) as references to concepts in std:: will consistently run into this area. This is why mangle-concepts1.C only refers to concepts in the global namespace so far. The library changes are to avoid trying to mangle builtins, which fails. Demangler support and test coverage is not complete yet. gcc/cp/ChangeLog: * cp-tree.h (TEMPLATE_ARGS_TYPE_CONSTRAINT_P): New. (get_concept_check_template): Declare. * constraint.cc (combine_constraint_expressions) (finish_shorthand_constraint): Use UNKNOWN_LOCATION. * pt.cc (convert_generic_types_to_packs): Likewise. * mangle.cc (write_constraint_expression) (write_tparms_constraints, write_type_constraint) (template_parm_natural_p, write_requirement) (write_requires_expr): New. (write_encoding): Mangle trailing requires-clause. (write_name): Pass parms to write_template_args. (write_template_param_decl): Factor out from... (write_closure_template_head): ...here. (write_template_args): Mangle non-natural parms and requires-clause. (write_expression): Handle REQUIRES_EXPR. include/ChangeLog: * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_CONSTRAINTS. libiberty/ChangeLog: * cp-demangle.c (d_make_comp): Handle DEMANGLE_COMPONENT_CONSTRAINTS. (d_count_templates_scopes): Likewise. (d_print_comp_inner): Likewise. (d_maybe_constraints): New. (d_encoding, d_template_args_1): Call it. (d_parmlist): Handle 'Q'. * testsuite/demangle-expected: Add some constraint tests. libstdc++-v3/ChangeLog: * include/std/bit: Avoid builtins in requires-clauses. * include/std/variant: Likewise. gcc/testsuite/ChangeLog: * g++.dg/abi/mangle10.C: Disable compat aliases. * g++.dg/abi/mangle52.C: Specify ABI 18. * g++.dg/cpp2a/class-deduction-alias3.C * g++.dg/cpp2a/class-deduction-alias8.C: Avoid builtins in requires-clauses. * g++.dg/abi/mangle-concepts1.C: New test. * g++.dg/abi/mangle-ttp1.C: New test.
Per itanium-cxx-abi/cxx-abi#24 and itanium-cxx-abi/cxx-abi#166 We need to mangle constraints to be able to distinguish between function templates that only differ in constraints. From the latter link, we want to use the template parameter mangling previously specified for lambdas to also make explicit the form of a template parameter where the argument is not a "natural" fit for it, such as when the parameter is constrained or deduced. I'm concerned about how the latter link changes the mangling for some C++98 and C++11 patterns, so I've limited template_parm_natural_p to avoid two cases found by running the testsuite with -Wabi forced on: template <class T, T V> T f() { return V; } int main() { return f<int,42>(); } template <int i> int max() { return i; } template <int i, int j, int... rest> int max() { int sub = max<j, rest...>(); return i > sub ? i : sub; } int main() { return max<1,2,3>(); } A third C++11 pattern is changed by this patch: template <template <typename...> class TT, typename... Ts> TT<Ts...> f(); template <typename> struct A { }; int main() { f<A,int>(); } I aim to resolve these with the ABI committee before GCC 14.1. We also need to resolve itanium-cxx-abi/cxx-abi#38 (mangling references to dependent template-ids where the name is fully resolved) as references to concepts in std:: will consistently run into this area. This is why mangle-concepts1.C only refers to concepts in the global namespace so far. The library changes are to avoid trying to mangle builtins, which fails. Demangler support and test coverage is not complete yet. gcc/cp/ChangeLog: * cp-tree.h (TEMPLATE_ARGS_TYPE_CONSTRAINT_P): New. (get_concept_check_template): Declare. * constraint.cc (combine_constraint_expressions) (finish_shorthand_constraint): Use UNKNOWN_LOCATION. * pt.cc (convert_generic_types_to_packs): Likewise. * mangle.cc (write_constraint_expression) (write_tparms_constraints, write_type_constraint) (template_parm_natural_p, write_requirement) (write_requires_expr): New. (write_encoding): Mangle trailing requires-clause. (write_name): Pass parms to write_template_args. (write_template_param_decl): Factor out from... (write_closure_template_head): ...here. (write_template_args): Mangle non-natural parms and requires-clause. (write_expression): Handle REQUIRES_EXPR. include/ChangeLog: * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_CONSTRAINTS. libiberty/ChangeLog: * cp-demangle.c (d_make_comp): Handle DEMANGLE_COMPONENT_CONSTRAINTS. (d_count_templates_scopes): Likewise. (d_print_comp_inner): Likewise. (d_maybe_constraints): New. (d_encoding, d_template_args_1): Call it. (d_parmlist): Handle 'Q'. * testsuite/demangle-expected: Add some constraint tests. libstdc++-v3/ChangeLog: * include/std/bit: Avoid builtins in requires-clauses. * include/std/variant: Likewise. gcc/testsuite/ChangeLog: * g++.dg/abi/mangle10.C: Disable compat aliases. * g++.dg/abi/mangle52.C: Specify ABI 18. * g++.dg/cpp2a/class-deduction-alias3.C * g++.dg/cpp2a/class-deduction-alias8.C: Avoid builtins in requires-clauses. * g++.dg/abi/mangle-concepts1.C: New test. * g++.dg/abi/mangle-ttp1.C: New test.
Alright, I should take another look at this. |
This includes the material from #47 (non-type template arguments), #63 (class constants), and the
template-param-decl
portions of #85 (C++20 lambda-expressions).@zygoloid gets credit for most of this, although I've made a few substantive changes from his suggestions.