diff options
Diffstat (limited to 'libiberty/d-demangle.c')
-rw-r--r-- | libiberty/d-demangle.c | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index cd3bc96..a2152cc 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -1,5 +1,5 @@ /* Demangler for the D programming language - Copyright (C) 2014-2020 Free Software Foundation, Inc. + Copyright (C) 2014-2021 Free Software Foundation, Inc. Written by Iain Buclaw (ibuclaw@gdcproject.org) This file is part of the libiberty library. @@ -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; } |