https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127002
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Patch I have been playing with:
--- a/gcc/cp/mangle.cc 2026-08-24 23:45:29.137180860 +0200
+++ b/gcc/cp/mangle.cc 2026-08-25 10:32:32.598011082 +0200
@@ -192,7 +192,7 @@ static void mangle_call_offset (const tr
static void write_mangled_name (const tree, bool);
static void write_encoding (const tree);
-static void write_name (tree, const int);
+static void write_name (tree, const bool = false);
static void write_abi_tags (tree);
static void write_unscoped_name (const tree);
static void write_unscoped_template_name (const tree);
@@ -914,7 +914,7 @@ write_type_constraint (tree cnst)
gcc_checking_assert (TREE_CODE (cnst) == TEMPLATE_ID_EXPR);
tree concept_decl = get_concept_check_template (cnst);
- write_name (concept_decl, 0);
+ write_name (concept_decl);
tree args = TREE_OPERAND (cnst, 1);
if (TREE_VEC_LENGTH (args) > 1)
{
@@ -936,13 +936,13 @@ write_encoding (const tree decl)
/* For overloaded operators write just the mangled name
without arguments. */
if (DECL_OVERLOADED_OPERATOR_P (decl))
- write_name (decl, /*ignore_local_scope=*/0);
+ write_name (decl);
else
write_source_name (DECL_NAME (decl));
return;
}
- write_name (decl, /*ignore_local_scope=*/0);
+ write_name (decl);
if (TREE_CODE (decl) == FUNCTION_DECL)
{
tree fn_type;
@@ -1086,14 +1086,14 @@ decl_mangling_context (tree decl)
::= <nested-name>
::= <local-name>
- If IGNORE_LOCAL_SCOPE is nonzero, this production of <name> is
+ If IGNORE_LOCAL_SCOPE is true, this production of <name> is
called from <local-name>, which mangles the enclosing scope
elsewhere and then uses this function to mangle just the part
underneath the function scope. So don't use the <local-name>
production, to avoid an infinite recursion. */
static void
-write_name (tree decl, const int ignore_local_scope)
+write_name (tree decl, const bool ignore_local_scope/*=false*/)
{
tree context;
@@ -2429,7 +2429,7 @@ write_local_name (tree function, const t
/* Now the <entity name>. Let write_name know its being called
from <local-name>, so it doesn't try to process the enclosing
function scope again. */
- write_name (entity, /*ignore_local_scope=*/1);
+ write_name (entity, /*ignore_local_scope=*/true);
if (DECL_DISCRIMINATOR_P (local_entity)
&& !(TREE_CODE (local_entity) == TYPE_DECL
&& TYPE_ANON_P (TREE_TYPE (local_entity))))
@@ -2640,7 +2640,7 @@ write_type (tree type)
type = CLASS_PLACEHOLDER_TEMPLATE (type);
if (find_substitution (type))
return;
- write_name (type, 0);
+ write_name (type);
break;
}
if (AUTO_IS_DECLTYPE (type))
@@ -3201,7 +3201,7 @@ write_method_parms (tree parm_types, con
static void
write_class_enum_type (const tree type)
{
- write_name (TYPE_NAME (type), /*ignore_local_scope=*/0);
+ write_name (TYPE_NAME (type));
}
/* Mangle a requirement REQ in a requires-expression. */
@@ -4188,15 +4188,16 @@ write_expression (tree expr)
::= sb <sb name> # structured binding
::= fn <function encoding> # function
::= pa [ <nonnegative number> ] _ <encoding> # fn param
- ::= en <prefix> <unqualified-name> # enumerator
+ ::= en <enum name> <unqualified-name> # enumerator
::= an [ <nonnegative number> ] _ # annotation
- ::= ta <alias prefix> <alias unqualified-name>
- [ <alias template-args> ] _ <type> # type alias
+ ::= ta <alias name> _ <type> # type alias
::= ty <type> # type
- ::= dm <prefix> <unqualified-name> # ns data member
- ::= da <prefix> [ <nonnegative number> ] _ # empty anon union
- # data member
- ::= un <prefix> [ <nonnegative number> ] _ # unnamed bitfld
+ ::= dm <class name> <unqualified-name> # ns data member
+ ::= da <class name> [ <nonnegative number> ] _ # empty anon
+ # union data
+ # member
+ ::= un <class name> [ <nonnegative number> ] _ # unnamed
+ # bitfld
::= ct [ <prefix> ] <unqualified-name> # class template
::= ft [ <prefix> ] <unqualified-name> # function template
::= vt [ <prefix> ] <unqualified-name> # variable template
@@ -4229,7 +4230,7 @@ write_reflection (tree refl)
if (strcmp (prefix, "vl") == 0 || strcmp (prefix, "ob") == 0)
write_expression (arg);
else if (strcmp (prefix, "vr") == 0 || strcmp (prefix, "sb") == 0)
- write_name (arg, 0);
+ write_name (arg);
else if (strcmp (prefix, "fn") == 0)
write_encoding (arg);
else if (strcmp (prefix, "pa") == 0)
@@ -4271,7 +4272,10 @@ write_reflection (tree refl)
tree ctx = decl_mangling_context (arg);
while (ctx && ANON_UNION_TYPE_P (ctx))
ctx = decl_mangling_context (TYPE_NAME (ctx));
- write_prefix (ctx);
+ if (TYPE_P (ctx))
+ write_name (TYPE_NAME (ctx));
+ else if (ctx != global_namespace)
+ write_name (ctx);
write_unqualified_name (arg);
}
else if (strcmp (prefix, "da") == 0)
@@ -4286,7 +4290,7 @@ write_reflection (tree refl)
&& ANON_AGGR_TYPE_P (TREE_TYPE (f))
&& anon_aggr_naming_decl (TREE_TYPE (f)) == NULL_TREE)
++idx;
- write_prefix (ctx);
+ write_name (TYPE_NAME (ctx));
write_compact_number (idx);
}
else if (strcmp (prefix, "un") == 0)
@@ -4298,7 +4302,7 @@ write_reflection (tree refl)
break;
else if (TREE_CODE (f) == FIELD_DECL && DECL_UNNAMED_BIT_FIELD (f))
++idx;
- write_prefix (decl_mangling_context (arg));
+ write_name (TYPE_NAME (decl_mangling_context (arg)));
write_compact_number (idx);
}
else if (strcmp (prefix, "ct") == 0
@@ -4594,7 +4598,7 @@ write_template_template_arg (const tree
if (find_substitution (decl))
return;
- write_name (decl, /*ignore_local_scope=*/0);
+ write_name (decl);
add_substitution (decl);
}
@@ -5325,7 +5329,7 @@ write_guarded_var_name (const tree varia
casing. */
write_string (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (variable)) + 2);
else
- write_name (variable, /*ignore_local_scope=*/0);
+ write_name (variable);
}
/* Return an identifier for the name of an initialization guard
The type alias case isn't handled in the patch yet at all, and there is a
problem
with the non-static data member "dm" mangling - in that case it strips
anonymous unions
and can in the end end up with global namespace or function scope. write_name
can't
handle global namespace (the patch for now doesn't call anything in that case)
and
for anonymous unions at function scope needs to use some kind of discriminator.
Am not sure whether using <name> is best, whether it wouldn't be better to keep
using
<prefix> and only for local names add <local-name> instead of <prefix>.
Jason, thoughts on this?