@@ -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_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 *,
struct dlang_info *, int);
@@ -573,9 +574,11 @@ dlang_attributes (string *decl, const char *mangled)
case 'g':
case 'h':
case 'k':
+ case 'n':
/* inout parameter is represented as 'Ng'.
vector parameter is represented as 'Nh'.
- return paramenter is represented as 'Nk'.
+ return parameter is represented as 'Nk'.
+ typeof(*null) parameter is represented as 'Nn'.
If we see this, then we know we're really in the
parameter list. Rewind and break. */
mangled--;
@@ -787,6 +790,12 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info)
string_append (decl, ")");
return mangled;
}
+ else if (*mangled == 'n') /* typeof(*null) */
+ {
+ mangled++;
+ string_append (decl, "typeof(*null)");
+ return mangled;
+ }
else
return NULL;
case 'A': /* dynamic array (T[]) */
@@ -884,7 +893,7 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info)
/* Basic types */
case 'n':
mangled++;
- string_append (decl, "none");
+ string_append (decl, "typeof(null)");
return mangled;
case 'v':
mangled++;
@@ -1035,6 +1044,25 @@ dlang_identifier (string *decl, const char *mangled, struct dlang_info *info)
&& (mangled[2] == 'T' || mangled[2] == 'U'))
return dlang_parse_template (decl, mangled, info, len);
+ /* There can be multiple different declarations in the same function that have
+ the same mangled name. To make the mangled names unique, a fake parent in
+ the form `__Sddd' is added to the symbol. */
+ if (len >= 4 && mangled[0] == '_' && mangled[1] == '_' && mangled[2] == 'S')
+ {
+ const char *numptr = mangled + 3;
+ while (numptr < (mangled + len) && ISDIGIT (*numptr))
+ numptr++;
+
+ if (mangled + len == numptr)
+ {
+ /* Skip over the fake parent. */
+ mangled += len;
+ return dlang_identifier (decl, mangled, info);
+ }
+
+ /* else demangle it as a plain identifier. */
+ }
+
return dlang_lname (decl, mangled, len);
}
@@ -1378,7 +1406,8 @@ dlang_parse_string (string *decl, const char *mangled)
/* Extract the static array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
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;
@@ -1389,7 +1418,7 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
string_append (decl, "[");
while (elements--)
{
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
@@ -1404,7 +1433,8 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
/* Extract the associative array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
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;
@@ -1415,12 +1445,12 @@ dlang_parse_assocarray (string *decl, const char *mangled)
string_append (decl, "[");
while (elements--)
{
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
string_append (decl, ":");
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
@@ -1435,7 +1465,8 @@ dlang_parse_assocarray (string *decl, const char *mangled)
/* Extract the struct literal value for NAME from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
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;
@@ -1449,7 +1480,7 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
string_append (decl, "(");
while (args--)
{
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
@@ -1464,7 +1495,8 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
/* Extract the value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
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')
return NULL;
@@ -1525,15 +1557,24 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
case 'A':
mangled++;
if (type == 'H')
- mangled = dlang_parse_assocarray (decl, mangled);
+ mangled = dlang_parse_assocarray (decl, mangled, info);
else
- mangled = dlang_parse_arrayliteral (decl, mangled);
+ mangled = dlang_parse_arrayliteral (decl, mangled, info);
break;
/* Struct values. */
case 'S':
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;
default:
@@ -1806,7 +1847,7 @@ dlang_template_args (string *decl, const char *mangled, struct dlang_info *info)
string_need (&name, 1);
*(name.p) = '\0';
- mangled = dlang_value (decl, mangled, name.b, type);
+ mangled = dlang_value (decl, mangled, name.b, type, info);
string_delete (&name);
break;
}
@@ -83,7 +83,11 @@ demangle.test(ulong)
#
--format=dlang
_D8demangle4testFnZv
-demangle.test(none)
+demangle.test(typeof(null))
+#
+--format=dlang
+_D8demangle4testFNnZv
+demangle.test(typeof(*null))
#
--format=dlang
_D8demangle4testFoZv
@@ -1414,3 +1418,31 @@ std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, "a", int, "b", in
--format=dlang
_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)
+#
+--format=dlang
+_D8demangle4mainFZ1xi
+demangle.main().x
+#
+--format=dlang
+_D8demangle4mainFZ4__S11xi
+demangle.main().x
+#
+--format=dlang
+_D8demangle4mainFZ1fMFNaNbNiNfZv
+demangle.main().f()
+#
+--format=dlang
+_D8demangle4mainFZ4__S11fMFNaNbNiNfZv
+demangle.main().f()
+#
+--format=dlang
+_D3mod4funcFZ__T6nestedTiZQkMFNaNbNiNfZi
+mod.func().nested!(int).nested()
+#
+--format=dlang
+_D3mod4funcFZ__T6nestedTiZ4__S1QpMFNaNbNiNfZi
+mod.func().nested!(int).nested()
+#
+--format=dlang
+_D6mangle__T8fun21753VSQv6S21753S1f_DQBj10__lambda71MFNaNbNiNfZvZQCbQp
+mangle.fun21753!(mangle.S21753(mangle.__lambda71())).fun21753