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  <jakub@redhat.com>

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.
This commit is contained in:
Jakub Jelinek 2024-01-13 10:23:53 +01:00
parent 34a827039f
commit 65388b2865
5 changed files with 107 additions and 7 deletions

View File

@ -1247,6 +1247,9 @@ write_nested_name (const tree decl)
write_char ('R'); write_char ('R');
} }
} }
else if (DECL_DECLARES_FUNCTION_P (decl)
&& DECL_XOBJ_MEMBER_FUNCTION_P (decl))
write_char ('H');
/* Is this a template instance? */ /* Is this a template instance? */
if (tree info = maybe_template_info (decl)) if (tree info = maybe_template_info (decl))

View File

@ -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 <int N, typename T>
static void bar (S, T);
template <int N, typename T>
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 <int N, typename T>
void
S::bar (S, T)
{
}
template <int N, typename T>
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_" } }

View File

@ -314,6 +314,8 @@ enum demangle_component_type
/* C++11: An rvalue reference modifying a member function. The one /* C++11: An rvalue reference modifying a member function. The one
subtree is the type which is being referenced. */ subtree is the type which is being referenced. */
DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS, DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS,
/* C++23: A member function with explict object parameter. */
DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION,
/* A vendor qualifier. The left subtree is the type which is being /* A vendor qualifier. The left subtree is the type which is being
qualified, and the right subtree is the name of the qualified, and the right subtree is the name of the
qualifier. */ qualifier. */

View File

@ -581,6 +581,7 @@ static char *d_demangle (const char *, int, size_t *);
case DEMANGLE_COMPONENT_CONST_THIS: \ case DEMANGLE_COMPONENT_CONST_THIS: \
case DEMANGLE_COMPONENT_REFERENCE_THIS: \ case DEMANGLE_COMPONENT_REFERENCE_THIS: \
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: \ case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: \
case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: \
case DEMANGLE_COMPONENT_TRANSACTION_SAFE: \ case DEMANGLE_COMPONENT_TRANSACTION_SAFE: \
case DEMANGLE_COMPONENT_NOEXCEPT: \ case DEMANGLE_COMPONENT_NOEXCEPT: \
case DEMANGLE_COMPONENT_THROW_SPEC case DEMANGLE_COMPONENT_THROW_SPEC
@ -749,6 +750,9 @@ d_dump (struct demangle_component *dc, int indent)
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
printf ("rvalue reference this\n"); printf ("rvalue reference this\n");
break; break;
case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION:
printf ("explicit object parameter\n");
break;
case DEMANGLE_COMPONENT_TRANSACTION_SAFE: case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
printf ("transaction_safe this\n"); printf ("transaction_safe this\n");
break; break;
@ -1547,6 +1551,8 @@ d_name (struct d_info *di, int substable)
/* <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E /* <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
::= N H <prefix> <unqualified-name> E
::= N H <template-prefix> <template-args> E
*/ */
static struct demangle_component * static struct demangle_component *
@ -1559,13 +1565,24 @@ d_nested_name (struct d_info *di)
if (! d_check_char (di, 'N')) if (! d_check_char (di, 'N'))
return NULL; return NULL;
pret = d_cv_qualifiers (di, &ret, 1); if (d_peek_char (di) == 'H')
if (pret == NULL) {
return NULL; d_advance (di, 1);
di->expansion += sizeof "this";
pret = &ret;
rqual = d_make_comp (di, DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION,
NULL, NULL);
}
else
{
pret = d_cv_qualifiers (di, &ret, 1);
if (pret == NULL)
return NULL;
/* Parse the ref-qualifier now and then attach it /* Parse the ref-qualifier now and then attach it
once we have something to attach it to. */ once we have something to attach it to. */
rqual = d_ref_qualifier (di, NULL); rqual = d_ref_qualifier (di, NULL);
}
*pret = d_prefix (di, 1); *pret = d_prefix (di, 1);
if (*pret == NULL) if (*pret == NULL)
@ -4427,6 +4444,7 @@ d_count_templates_scopes (struct d_print_info *dpi,
case DEMANGLE_COMPONENT_CONST_THIS: case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS: case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION:
case DEMANGLE_COMPONENT_TRANSACTION_SAFE: case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
case DEMANGLE_COMPONENT_NOEXCEPT: case DEMANGLE_COMPONENT_NOEXCEPT:
case DEMANGLE_COMPONENT_THROW_SPEC: case DEMANGLE_COMPONENT_THROW_SPEC:
@ -6521,6 +6539,8 @@ d_print_mod (struct d_print_info *dpi, int options,
case DEMANGLE_COMPONENT_RVALUE_REFERENCE: case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
d_append_string (dpi, "&&"); d_append_string (dpi, "&&");
return; return;
case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION:
return;
case DEMANGLE_COMPONENT_COMPLEX: case DEMANGLE_COMPONENT_COMPLEX:
d_append_string (dpi, " _Complex"); d_append_string (dpi, " _Complex");
return; return;
@ -6559,11 +6579,13 @@ d_print_function_type (struct d_print_info *dpi, int options,
{ {
int need_paren; int need_paren;
int need_space; int need_space;
int xobj_memfn;
struct d_print_mod *p; struct d_print_mod *p;
struct d_print_mod *hold_modifiers; struct d_print_mod *hold_modifiers;
need_paren = 0; need_paren = 0;
need_space = 0; need_space = 0;
xobj_memfn = 0;
for (p = mods; p != NULL; p = p->next) for (p = mods; p != NULL; p = p->next)
{ {
if (p->printed) if (p->printed)
@ -6586,7 +6608,8 @@ d_print_function_type (struct d_print_info *dpi, int options,
need_space = 1; need_space = 1;
need_paren = 1; need_paren = 1;
break; break;
FNQUAL_COMPONENT_CASE: case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION:
xobj_memfn = 1;
break; break;
default: default:
break; break;
@ -6617,6 +6640,8 @@ d_print_function_type (struct d_print_info *dpi, int options,
d_append_char (dpi, ')'); d_append_char (dpi, ')');
d_append_char (dpi, '('); d_append_char (dpi, '(');
if (xobj_memfn)
d_append_string (dpi, "this ");
if (d_right (dc) != NULL) if (d_right (dc) != NULL)
d_print_comp (dpi, options, d_right (dc)); d_print_comp (dpi, options, d_right (dc));

View File

@ -1700,3 +1700,12 @@ void f<int>() requires C<int>
# requires after () # requires after ()
_Z1fIiEvvQ1CIT_E _Z1fIiEvvQ1CIT_E
void f<int>() requires C<int> void f<int>() requires C<int>
_ZNH1S3fooES_
S::foo(this S)
_ZNH1S3barILi5EiEEvS_T0_
void S::bar<5, int>(this S, int)
_ZNH1S3bazERKS_
S::baz(this S const&)