From 65388b28656d65595bdaf191df85af81c35ca638 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 13 Jan 2024 10:23:53 +0100 Subject: c++, demangle: Implement https://github.com/itanium-cxx-abi/cxx-abi/issues/148 non-proposal The following patch attempts to implement what apparently clang++ implemented for explicit object member function mangling, but nobody actually proposed in patch form in https://github.com/itanium-cxx-abi/cxx-abi/issues/148 2024-01-13 Jakub Jelinek gcc/cp/ * mangle.cc (write_nested_name): Mangle explicit object member functions with H as per https://github.com/itanium-cxx-abi/cxx-abi/issues/148 non-proposal. gcc/testsuite/ * g++.dg/abi/mangle79.C: New test. include/ * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. libiberty/ * cp-demangle.c (FNQUAL_COMPONENT_CASE): Add case for DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. (d_dump): Handle DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. (d_nested_name): Parse H after N in nested name. (d_count_templates_scopes): Handle DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION. (d_print_mod): Likewise. (d_print_function_type): Likewise. * testsuite/demangle-expected: Add tests for explicit object member functions. --- gcc/cp/mangle.cc | 3 ++ gcc/testsuite/g++.dg/abi/mangle79.C | 61 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 gcc/testsuite/g++.dg/abi/mangle79.C (limited to 'gcc') diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 7d8f443..a04bc58 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -1247,6 +1247,9 @@ write_nested_name (const tree decl) write_char ('R'); } } + else if (DECL_DECLARES_FUNCTION_P (decl) + && DECL_XOBJ_MEMBER_FUNCTION_P (decl)) + write_char ('H'); /* Is this a template instance? */ if (tree info = maybe_template_info (decl)) diff --git a/gcc/testsuite/g++.dg/abi/mangle79.C b/gcc/testsuite/g++.dg/abi/mangle79.C new file mode 100644 index 0000000..99ae822 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle79.C @@ -0,0 +1,61 @@ +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct S { + static void foo (S); + void foo (this S); // { dg-warning "explicit object member function only available with" "" { target c++20_down } } + template + static void bar (S, T); + template + void bar (this S, T); // { dg-warning "explicit object member function only available with" "" { target c++20_down } } + static void baz (const S &); + void baz (this const S &); // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +}; + +void +S::foo (S) +{ +} + +void +S::foo (this S) // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +{ +} + +template +void +S::bar (S, T) +{ +} + +template +void +S::bar (this S, T) // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +{ +} + +void +S::baz (const S &) +{ +} + +void +S::baz (this const S &) // { dg-warning "explicit object member function only available with" "" { target c++20_down } } +{ +} + +void +qux (S *p) +{ + S::foo (*p); + p->foo (); + S::bar <5> (*p, 0); + p->bar <5> (0); +} + +// { dg-final { scan-assembler "_ZN1S3fooES_" } } +// { dg-final { scan-assembler "_ZNH1S3fooES_" } } +// { dg-final { scan-assembler "_ZN1S3barILi5EiEEvS_T0_" } } +// { dg-final { scan-assembler "_ZNH1S3barILi5EiEEvS_T0_" } } +// { dg-final { scan-assembler "_ZN1S3bazERKS_" } } +// { dg-final { scan-assembler "_ZNH1S3bazERKS_" } } -- cgit v1.1