--- binutils.orig/include/demangle.h 2024-01-17 09:54:10.945686323 +0000 +++ binutils-2.41/include/demangle.h 2024-01-17 09:54:55.696760281 +0000 @@ -1,5 +1,5 @@ /* Defs for interface to demanglers. - Copyright (C) 1992-2023 Free Software Foundation, Inc. + Copyright (C) 1992-2024 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License @@ -448,6 +448,8 @@ enum demangle_component_type DEMANGLE_COMPONENT_TRANSACTION_SAFE, /* A cloned function. */ DEMANGLE_COMPONENT_CLONE, + /* A member-like friend function. */ + DEMANGLE_COMPONENT_FRIEND, DEMANGLE_COMPONENT_NOEXCEPT, DEMANGLE_COMPONENT_THROW_SPEC, @@ -464,6 +466,8 @@ enum demangle_component_type DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM, DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM, + DEMANGLE_COMPONENT_CONSTRAINTS, + /* A builtin type with argument. This holds the builtin type information. */ DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE diff -rup binutils.orig/libiberty/cp-demangle.c binutils-2.41/libiberty/cp-demangle.c --- binutils.orig/libiberty/cp-demangle.c 2024-01-17 09:54:11.323686947 +0000 +++ binutils-2.41/libiberty/cp-demangle.c 2024-01-17 09:54:42.468738420 +0000 @@ -1,5 +1,5 @@ /* Demangler for g++ V3 ABI. - Copyright (C) 2003-2023 Free Software Foundation, Inc. + Copyright (C) 2003-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor . This file is part of the libiberty library, which is part of GCC. @@ -993,6 +993,7 @@ d_make_comp (struct d_info *di, enum dem case DEMANGLE_COMPONENT_VECTOR_TYPE: case DEMANGLE_COMPONENT_CLONE: case DEMANGLE_COMPONENT_MODULE_ENTITY: + case DEMANGLE_COMPONENT_CONSTRAINTS: if (left == NULL || right == NULL) return NULL; break; @@ -1036,6 +1037,7 @@ d_make_comp (struct d_info *di, enum dem case DEMANGLE_COMPONENT_TEMPLATE_NON_TYPE_PARM: case DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM: case DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM: + case DEMANGLE_COMPONENT_FRIEND: if (left == NULL) return NULL; break; @@ -1344,6 +1346,22 @@ is_ctor_dtor_or_conversion (struct deman } } +/* [ Q ] */ + +static struct demangle_component * +d_maybe_constraints (struct d_info *di, struct demangle_component *dc) +{ + if (d_peek_char (di) == 'Q') + { + d_advance (di, 1); + struct demangle_component *expr = d_expression (di); + if (expr == NULL) + return NULL; + dc = d_make_comp (di, DEMANGLE_COMPONENT_CONSTRAINTS, dc, expr); + } + return dc; +} + /* ::= <(function) name> ::= <(data) name> ::= @@ -1397,21 +1415,21 @@ d_encoding (struct d_info *di, int top_l struct demangle_component *ftype; ftype = d_bare_function_type (di, has_return_type (dc)); - if (ftype) - { - /* If this is a non-top-level local-name, clear the - return type, so it doesn't confuse the user by - being confused with the return type of whaever - this is nested within. */ - if (!top_level && dc->type == DEMANGLE_COMPONENT_LOCAL_NAME - && ftype->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) - d_left (ftype) = NULL; + if (!ftype) + return NULL; - dc = d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, - dc, ftype); - } - else - dc = NULL; + /* If this is a non-top-level local-name, clear the + return type, so it doesn't confuse the user by + being confused with the return type of whaever + this is nested within. */ + if (!top_level && dc->type == DEMANGLE_COMPONENT_LOCAL_NAME + && ftype->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) + d_left (ftype) = NULL; + + ftype = d_maybe_constraints (di, ftype); + + dc = d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, + dc, ftype); } } } @@ -1681,6 +1699,7 @@ d_maybe_module_name (struct d_info *di, /* ::= [] [] ::= [] [] ::= [] [] + ::= [] F [] ::= [] [] ::= [] DC + E [] ::= L [] @@ -1692,11 +1711,18 @@ d_unqualified_name (struct d_info *di, s { struct demangle_component *ret; char peek; + int member_like_friend = 0; if (!d_maybe_module_name (di, &module)) return NULL; peek = d_peek_char (di); + if (peek == 'F') + { + member_like_friend = 1; + d_advance (di, 1); + peek = d_peek_char (di); + } if (IS_DIGIT (peek)) ret = d_source_name (di); else if (IS_LOWER (peek)) @@ -1773,6 +1799,8 @@ d_unqualified_name (struct d_info *di, s ret = d_make_comp (di, DEMANGLE_COMPONENT_MODULE_ENTITY, ret, module); if (d_peek_char (di) == 'B') ret = d_abi_tags (di, ret); + if (member_like_friend) + ret = d_make_comp (di, DEMANGLE_COMPONENT_FRIEND, ret, NULL); if (scope) ret = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, scope, ret); @@ -3012,7 +3040,7 @@ d_parmlist (struct d_info *di) struct demangle_component *type; char peek = d_peek_char (di); - if (peek == '\0' || peek == 'E' || peek == '.') + if (peek == '\0' || peek == 'E' || peek == '.' || peek == 'Q') break; if ((peek == 'R' || peek == 'O') && d_peek_next_char (di) == 'E') @@ -3248,7 +3276,7 @@ d_template_args (struct d_info *di) return d_template_args_1 (di); } -/* * E */ +/* * [Q ] E */ static struct demangle_component * d_template_args_1 (struct d_info *di) @@ -3284,13 +3312,17 @@ d_template_args_1 (struct d_info *di) return NULL; pal = &d_right (*pal); - if (d_peek_char (di) == 'E') - { - d_advance (di, 1); - break; - } + char peek = d_peek_char (di); + if (peek == 'E' || peek == 'Q') + break; } + al = d_maybe_constraints (di, al); + + if (d_peek_char (di) != 'E') + return NULL; + d_advance (di, 1); + di->last_name = hold_last_name; return al; @@ -4431,6 +4463,7 @@ d_count_templates_scopes (struct d_print case DEMANGLE_COMPONENT_PACK_EXPANSION: case DEMANGLE_COMPONENT_TAGGED_NAME: case DEMANGLE_COMPONENT_CLONE: + case DEMANGLE_COMPONENT_CONSTRAINTS: recurse_left_right: /* PR 89394 - Check for too much recursion. */ if (dpi->recursion > DEMANGLE_RECURSION_LIMIT) @@ -4459,6 +4492,7 @@ d_count_templates_scopes (struct d_print case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: case DEMANGLE_COMPONENT_MODULE_ENTITY: + case DEMANGLE_COMPONENT_FRIEND: d_count_templates_scopes (dpi, d_left (dc)); break; @@ -5189,6 +5223,22 @@ d_print_comp_inner (struct d_print_info dpt.next = dpi->templates; dpi->templates = &dpt; dpt.template_decl = typed_name; + + /* Constraints are mangled as part of the template argument list, + so they wrap the _TEMPLATE_ARGLIST. But + d_lookup_template_argument expects the RHS of _TEMPLATE to be + the _ARGLIST, and constraints need to refer to these args. So + move the _CONSTRAINTS out of the _TEMPLATE and onto the type. + This will result in them being printed after the () like a + trailing requires-clause, but that seems like our best option + given that we aren't printing a template-head. */ + struct demangle_component *tnr = d_right (typed_name); + if (tnr->type == DEMANGLE_COMPONENT_CONSTRAINTS) + { + d_right (typed_name) = d_left (tnr); + d_left (tnr) = d_right (dc); + d_right (dc) = tnr; + } } d_print_comp (dpi, options, d_right (dc)); @@ -6197,6 +6247,11 @@ d_print_comp_inner (struct d_print_info d_append_char (dpi, ']'); return; + case DEMANGLE_COMPONENT_FRIEND: + d_print_comp (dpi, options, d_left (dc)); + d_append_string (dpi, "[friend]"); + return; + case DEMANGLE_COMPONENT_TEMPLATE_HEAD: { d_append_char (dpi, '<'); @@ -6231,6 +6286,12 @@ d_print_comp_inner (struct d_print_info d_append_string (dpi, "..."); return; + case DEMANGLE_COMPONENT_CONSTRAINTS: + d_print_comp (dpi, options, d_left (dc)); + d_append_string (dpi, " requires "); + d_print_comp (dpi, options, d_right (dc)); + return; + default: d_print_error (dpi); return; --- binutils.orig/include/demangle.h 2024-01-17 11:06:11.111229985 +0000 +++ binutils-2.41/include/demangle.h 2024-01-17 11:06:21.281242709 +0000 @@ -314,6 +314,8 @@ enum demangle_component_type /* C++11: An rvalue reference modifying a member function. The one subtree is the type which is being referenced. */ 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 qualified, and the right subtree is the name of the qualifier. */ --- binutils.orig/libiberty/cp-demangle.c 2024-01-17 11:06:11.246230153 +0000 +++ binutils-2.41/libiberty/cp-demangle.c 2024-01-17 11:06:21.282242710 +0000 @@ -581,6 +581,7 @@ static char *d_demangle (const char *, i case DEMANGLE_COMPONENT_CONST_THIS: \ case DEMANGLE_COMPONENT_REFERENCE_THIS: \ case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: \ + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: \ case DEMANGLE_COMPONENT_TRANSACTION_SAFE: \ case DEMANGLE_COMPONENT_NOEXCEPT: \ case DEMANGLE_COMPONENT_THROW_SPEC @@ -749,6 +750,9 @@ d_dump (struct demangle_component *dc, i case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: printf ("rvalue reference this\n"); break; + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: + printf ("explicit object parameter\n"); + break; case DEMANGLE_COMPONENT_TRANSACTION_SAFE: printf ("transaction_safe this\n"); break; @@ -1547,6 +1551,8 @@ d_name (struct d_info *di, int substable /* ::= N [] [] E ::= N [] [] E + ::= N H E + ::= N H E */ static struct demangle_component * @@ -1559,13 +1565,24 @@ d_nested_name (struct d_info *di) if (! d_check_char (di, 'N')) return NULL; - pret = d_cv_qualifiers (di, &ret, 1); - if (pret == NULL) - return NULL; + if (d_peek_char (di) == 'H') + { + 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 - once we have something to attach it to. */ - rqual = d_ref_qualifier (di, NULL); + /* Parse the ref-qualifier now and then attach it + once we have something to attach it to. */ + rqual = d_ref_qualifier (di, NULL); + } *pret = d_prefix (di, 1); if (*pret == NULL) @@ -4427,6 +4444,7 @@ d_count_templates_scopes (struct d_print case DEMANGLE_COMPONENT_CONST_THIS: case DEMANGLE_COMPONENT_REFERENCE_THIS: case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: case DEMANGLE_COMPONENT_TRANSACTION_SAFE: case DEMANGLE_COMPONENT_NOEXCEPT: case DEMANGLE_COMPONENT_THROW_SPEC: @@ -6521,6 +6539,8 @@ d_print_mod (struct d_print_info *dpi, i case DEMANGLE_COMPONENT_RVALUE_REFERENCE: d_append_string (dpi, "&&"); return; + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: + return; case DEMANGLE_COMPONENT_COMPLEX: d_append_string (dpi, " _Complex"); return; @@ -6559,11 +6579,13 @@ d_print_function_type (struct d_print_in { int need_paren; int need_space; + int xobj_memfn; struct d_print_mod *p; struct d_print_mod *hold_modifiers; need_paren = 0; need_space = 0; + xobj_memfn = 0; for (p = mods; p != NULL; p = p->next) { if (p->printed) @@ -6586,7 +6608,8 @@ d_print_function_type (struct d_print_in need_space = 1; need_paren = 1; break; - FNQUAL_COMPONENT_CASE: + case DEMANGLE_COMPONENT_XOBJ_MEMBER_FUNCTION: + xobj_memfn = 1; break; default: break; @@ -6617,6 +6640,8 @@ d_print_function_type (struct d_print_in d_append_char (dpi, ')'); d_append_char (dpi, '('); + if (xobj_memfn) + d_append_string (dpi, "this "); if (d_right (dc) != NULL) d_print_comp (dpi, options, d_right (dc));