libiberty: Add support for demangling D function literals as template value parameters

The D language now allows instantiating templates using struct literals
that have function literal fields as a value argument.

libiberty/ChangeLog:

	* d-demangle.c (dlang_parse_arrayliteral): Add 'info' parameter.
	(dlang_parse_assocarray): Likewise.
	(dlang_parse_structlit): Likewise.
	(dlang_value): Likewise.  Handle function literal symbols.
	(dlang_template_args): Pass 'info' to dlang_value.
	* testsuite/d-demangle-expected: Add new test.
This commit is contained in:
Iain Buclaw 2021-08-29 20:04:24 +02:00
parent 0e32a5aa8b
commit 34f3e0657a
2 changed files with 31 additions and 13 deletions

View File

@ -191,7 +191,8 @@ static const char *dlang_function_args (string *, const char *,
static const char *dlang_type (string *, const char *, struct dlang_info *); static const char *dlang_type (string *, const char *, struct dlang_info *);
static const char *dlang_value (string *, const char *, const char *, char); static const char *dlang_value (string *, const char *, const char *, char,
struct dlang_info *);
static const char *dlang_parse_qualified (string *, const char *, static const char *dlang_parse_qualified (string *, const char *,
struct dlang_info *, int); struct dlang_info *, int);
@ -1386,7 +1387,8 @@ dlang_parse_string (string *decl, const char *mangled)
/* Extract the static array value from MANGLED and append it to DECL. /* Extract the static array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */ Return the remaining string on success or NULL on failure. */
static const char * static const char *
dlang_parse_arrayliteral (string *decl, const char *mangled) dlang_parse_arrayliteral (string *decl, const char *mangled,
struct dlang_info *info)
{ {
unsigned long elements; unsigned long elements;
@ -1397,7 +1399,7 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
string_append (decl, "["); string_append (decl, "[");
while (elements--) while (elements--)
{ {
mangled = dlang_value (decl, mangled, NULL, '\0'); mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL) if (mangled == NULL)
return NULL; return NULL;
@ -1412,7 +1414,8 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
/* Extract the associative array value from MANGLED and append it to DECL. /* Extract the associative array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */ Return the remaining string on success or NULL on failure. */
static const char * static const char *
dlang_parse_assocarray (string *decl, const char *mangled) dlang_parse_assocarray (string *decl, const char *mangled,
struct dlang_info *info)
{ {
unsigned long elements; unsigned long elements;
@ -1423,12 +1426,12 @@ dlang_parse_assocarray (string *decl, const char *mangled)
string_append (decl, "["); string_append (decl, "[");
while (elements--) while (elements--)
{ {
mangled = dlang_value (decl, mangled, NULL, '\0'); mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL) if (mangled == NULL)
return NULL; return NULL;
string_append (decl, ":"); string_append (decl, ":");
mangled = dlang_value (decl, mangled, NULL, '\0'); mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL) if (mangled == NULL)
return NULL; return NULL;
@ -1443,7 +1446,8 @@ dlang_parse_assocarray (string *decl, const char *mangled)
/* Extract the struct literal value for NAME from MANGLED and append it to DECL. /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */ Return the remaining string on success or NULL on failure. */
static const char * static const char *
dlang_parse_structlit (string *decl, const char *mangled, const char *name) dlang_parse_structlit (string *decl, const char *mangled, const char *name,
struct dlang_info *info)
{ {
unsigned long args; unsigned long args;
@ -1457,7 +1461,7 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
string_append (decl, "("); string_append (decl, "(");
while (args--) while (args--)
{ {
mangled = dlang_value (decl, mangled, NULL, '\0'); mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL) if (mangled == NULL)
return NULL; return NULL;
@ -1472,7 +1476,8 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
/* Extract the value from MANGLED and append it to DECL. /* Extract the value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */ Return the remaining string on success or NULL on failure. */
static const char * static const char *
dlang_value (string *decl, const char *mangled, const char *name, char type) dlang_value (string *decl, const char *mangled, const char *name, char type,
struct dlang_info *info)
{ {
if (mangled == NULL || *mangled == '\0') if (mangled == NULL || *mangled == '\0')
return NULL; return NULL;
@ -1533,15 +1538,24 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
case 'A': case 'A':
mangled++; mangled++;
if (type == 'H') if (type == 'H')
mangled = dlang_parse_assocarray (decl, mangled); mangled = dlang_parse_assocarray (decl, mangled, info);
else else
mangled = dlang_parse_arrayliteral (decl, mangled); mangled = dlang_parse_arrayliteral (decl, mangled, info);
break; break;
/* Struct values. */ /* Struct values. */
case 'S': case 'S':
mangled++; mangled++;
mangled = dlang_parse_structlit (decl, mangled, name); mangled = dlang_parse_structlit (decl, mangled, name, info);
break;
/* Function literal symbol. */
case 'f':
mangled++;
if (strncmp (mangled, "_D", 2) != 0
|| !dlang_symbol_name_p (mangled + 2, info))
return NULL;
mangled = dlang_parse_mangle (decl, mangled, info);
break; break;
default: default:
@ -1814,7 +1828,7 @@ dlang_template_args (string *decl, const char *mangled, struct dlang_info *info)
string_need (&name, 1); string_need (&name, 1);
*(name.p) = '\0'; *(name.p) = '\0';
mangled = dlang_value (decl, mangled, name.b, type); mangled = dlang_value (decl, mangled, name.b, type, info);
string_delete (&name); string_delete (&name);
break; break;
} }

View File

@ -1418,3 +1418,7 @@ std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, "a", int, "b", in
--format=dlang --format=dlang
_D3std3uni__T6toCaseS_DQvQt12toLowerIndexFNaNbNiNewZtVii1043S_DQCjQCi10toLowerTabFNaNbNiNemZwSQDo5ascii7toLowerTAyaZQDzFNaNeQmZ14__foreachbody2MFNaNeKmKwZ14__foreachbody3MFNaNeKwZi _D3std3uni__T6toCaseS_DQvQt12toLowerIndexFNaNbNiNewZtVii1043S_DQCjQCi10toLowerTabFNaNbNiNemZwSQDo5ascii7toLowerTAyaZQDzFNaNeQmZ14__foreachbody2MFNaNeKmKwZ14__foreachbody3MFNaNeKwZi
std.uni.toCase!(std.uni.toLowerIndex(dchar), 1043, std.uni.toLowerTab(ulong), std.ascii.toLower, immutable(char)[]).toCase(immutable(char)[]).__foreachbody2(ref ulong, ref dchar).__foreachbody3(ref dchar) std.uni.toCase!(std.uni.toLowerIndex(dchar), 1043, std.uni.toLowerTab(ulong), std.ascii.toLower, immutable(char)[]).toCase(immutable(char)[]).__foreachbody2(ref ulong, ref dchar).__foreachbody3(ref dchar)
#
--format=dlang
_D6mangle__T8fun21753VSQv6S21753S1f_DQBj10__lambda71MFNaNbNiNfZvZQCbQp
mangle.fun21753!(mangle.S21753(mangle.__lambda71())).fun21753