[PATCH v2 2/2] Sync libiberty with gcc upstream

Iain Buclaw
2015-06-19T15:24:32Z

[-- Attachment #1: Type: text/plain, Size: 145 bytes --]

Second downstream patch with dlang demangling related changes only.
Should be a more straightforward read than the other one.

Regards
Iain

---

[-- Attachment #2: sync_upstream_libiberty-2.patch --]
[-- Type: text/x-diff, Size: 29994 bytes --]

libiberty/
2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_symbol_kinds): New enum.
(dlang_parse_symbol): Update signature. Handle an ambiguity between
pascal functions and template value arguments. Only check for a type
if parsing a function, or at the top level. Return failure if the
entire symbol was not successfully demangled.
(dlang_identifier): Update signature. Handle an ambiguity between two
adjacent digits in a mangled symbol string.
(dlang_type): Update call to dlang_parse_symbol.
(dlang_template_args): Likewise.
(dlang_parse_template): Likewise.
(dlang_demangle): Likewise.
* testsuite/d-demangle-expected: Fix bad tests found, and add problematic
examples to the unittests.

2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_template_args): Skip over specialized template
parameters in mangled symbol.
* testsuite/d-demangle-expected: Add coverage and unittest for specialized
template parameters.

2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_type): Handle cent and ucent types.
* testsuite/d-demangle-expected: Add coverage tests for cent and ucent.

2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_attributes): Handle return attributes, ignoring
return parameters in the mangled string. Return NULL if have encountered
an unknown attribute.
(dlang_function_args): Handle return parameters in the mangled string.
* testsuite/d-demangle-expected: Add coverage tests for functions with
return parameters and return attributes.

2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_identifier): Check encoded length of identifier
to verify strncmp matches entire string.
* testsuite/d-demangle-expected: Fix wrong test for postblit symbol.

2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_type_modifiers): New function.
(dlang_type_modifier_p): New function.
(dlang_call_convention_p): Ignore any kind of type modifier.
(dlang_type): Handle and emit the type modifier after delegate types.
(dlang_parse_symbol): Handle and emit the type modifier after the symbol.
* testsuite/d-demangle-expected: Add coverage tests for all valid
usages of function symbols with type modifiers.

2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_call_convention): Return NULL if have reached the
end of the symbol, but expected something to read.
(dlang_attributes): Likewise.
(dlang_function_type): Likewise.
(dlang_type): Likewise.
(dlang_identifier): Likewise.
(dlang_value): Likewise.

2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_parse_string): Represent embedded whitespace or
non-printable characters as hex or escape sequences.
* testsuite/d-demangle-expected: Add test for templates with tabs and
newlines embedded into the signature.

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index bb481c0..a2a3b32 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -1,5 +1,5 @@
/* Demangler for the D programming language
- Copyright 2014 Free Software Foundation, Inc.
+ Copyright 2014, 2015 Free Software Foundation, Inc.
Written by Iain Buclaw (ibuclaw@gdcproject.org)

This file is part of the libiberty library.
@@ -165,6 +165,21 @@ string_prepend (string *p, const char *s)
}
}

+/* What kinds of symbol we could be parsing. */
+enum dlang_symbol_kinds
+{
+ /* Top-level symbol, needs it's type checked. */
+ dlang_top_level,
+ /* Function symbol, needs it's type checked. */
+ dlang_function,
+ /* Strongly typed name, such as for classes, structs and enums. */
+ dlang_type_name,
+ /* Template identifier. */
+ dlang_template_ident,
+ /* Template symbol parameter. */
+ dlang_template_param
+};
+
/* Prototypes for forward referenced functions */
static const char *dlang_function_args (string *, const char *);

@@ -172,7 +187,8 @@ static const char *dlang_type (string *, const char *);

static const char *dlang_value (string *, const char *, const char *, char);

-static const char *dlang_parse_symbol (string *, const char *);
+static const char *dlang_parse_symbol (string *, const char *,
+ enum dlang_symbol_kinds);

static const char *dlang_parse_tuple (string *, const char *);

@@ -185,7 +201,7 @@ static const char *
dlang_call_convention (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
- return mangled;
+ return NULL;

switch (*mangled)
{
@@ -215,13 +231,51 @@ dlang_call_convention (string *decl, const char *mangled)
return mangled;
}

+/* Extract the type modifiers from MANGLED and append them to DECL.
+ Returns the remaining signature on success or NULL on failure. */
+static const char *
+dlang_type_modifiers (string *decl, const char *mangled)
+{
+ if (mangled == NULL || *mangled == '\0')
+ return NULL;
+
+ switch (*mangled)
+ {
+ case 'x': /* const */
+ mangled++;
+ string_append (decl, " const");
+ return mangled;
+ case 'y': /* immutable */
+ mangled++;
+ string_append (decl, " immutable");
+ return mangled;
+ case 'O': /* shared */
+ mangled++;
+ string_append (decl, " shared");
+ return dlang_type_modifiers (decl, mangled);
+ case 'N':
+ mangled++;
+ if (*mangled == 'g') /* wild */
+ {
+ mangled++;
+ string_append (decl, " inout");
+ return dlang_type_modifiers (decl, mangled);
+ }
+ else
+ return NULL;
+
+ default:
+ return mangled;
+ }
+}
+
/* Demangle the D function attributes from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_attributes (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
- return mangled;
+ return NULL;

while (*mangled == 'N')
{
@@ -254,8 +308,10 @@ dlang_attributes (string *decl, const char *mangled)
continue;
case 'g':
case 'h':
+ case 'k':
/* inout parameter is represented as 'Ng'.
vector parameter is represented as 'Nh'.
+ return paramenter is represented as 'Nk'.
If we see this, then we know we're really in the
parameter list. Rewind and break. */
mangled--;
@@ -264,6 +320,13 @@ dlang_attributes (string *decl, const char *mangled)
mangled++;
string_append (decl, "@nogc ");
continue;
+ case 'j': /* return */
+ mangled++;
+ string_append (decl, "return ");
+ continue;
+
+ default: /* unknown attribute */
+ return NULL;
}
break;
}
@@ -280,7 +343,7 @@ dlang_function_type (string *decl, const char *mangled)
size_t szattr, szargs, sztype;

if (mangled == NULL || *mangled == '\0')
- return mangled;
+ return NULL;

/* The order of the mangled string is:
CallConvention FuncAttrs Arguments ArgClose Type
@@ -353,6 +416,12 @@ dlang_function_args (string *decl, const char *mangled)
string_append (decl, "scope ");
}

+ if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
+ {
+ mangled += 2;
+ string_append (decl, "return ");
+ }
+
switch (*mangled)
{
case 'J': /* out(T) */
@@ -380,7 +449,7 @@ static const char *
dlang_type (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
- return mangled;
+ return NULL;

switch (*mangled)
{
@@ -474,12 +543,24 @@ dlang_type (string *decl, const char *mangled)
case 'E': /* enum T */
case 'T': /* typedef T */
mangled++;
- return dlang_parse_symbol (decl, mangled);
+ return dlang_parse_symbol (decl, mangled, dlang_type_name);
case 'D': /* delegate T */
+ {
+ string mods;
+ size_t szmods;
mangled++;
+
+ string_init (&mods);
+ mangled = dlang_type_modifiers (&mods, mangled);
+ szmods = string_length (&mods);
+
mangled = dlang_function_type (decl, mangled);
string_append (decl, "delegate");
+ string_appendn (decl, mods.b, szmods);
+
+ string_delete (&mods);
return mangled;
+ }
case 'B': /* tuple T */
mangled++;
return dlang_parse_tuple (decl, mangled);
@@ -588,6 +669,20 @@ dlang_type (string *decl, const char *mangled)
mangled++;
string_append (decl, "dchar");
return mangled;
+ case 'z':
+ mangled++;
+ switch (*mangled)
+ {
+ case 'i':
+ mangled++;
+ string_append (decl, "cent");
+ return mangled;
+ case 'k':
+ mangled++;
+ string_append (decl, "ucent");
+ return mangled;
+ }
+ return NULL;

default: /* unhandled */
return NULL;
@@ -597,97 +692,162 @@ dlang_type (string *decl, const char *mangled)
/* Extract the identifier from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
-dlang_identifier (string *decl, const char *mangled)
+dlang_identifier (string *decl, const char *mangled,
+ enum dlang_symbol_kinds kind)
{
+ char *endptr;
+ long len;
+
if (mangled == NULL || *mangled == '\0')
- return mangled;
+ return NULL;

- if (ISDIGIT (*mangled))
+ len = strtol (mangled, &endptr, 10);
+
+ if (endptr == NULL || len <= 0)
+ return NULL;
+
+ /* In template parameter symbols, the first character of the mangled
+ name can be a digit. This causes ambiguity issues because the
+ digits of the two numbers are adjacent. */
+ if (kind == dlang_template_param)
{
- char *endptr;
- long i = strtol (mangled, &endptr, 10);
+ long psize = len;
+ char *pend;
+ int saved = string_length (decl);

- if (endptr == NULL || i <= 0 || strlen (endptr) < (size_t) i)
+ /* Work backwards until a match is found. */
+ for (pend = endptr; endptr != NULL; pend--)
+ {
+ mangled = pend;
+
+ /* Reached the beginning of the pointer to the name length,
+ try parsing the entire symbol. */
+ if (psize == 0)
+ {
+ psize = len;
+ pend = endptr;
+ endptr = NULL;
+ }
+
+ /* Check whether template parameter is a function with a valid
+ return type or an untyped identifier. */
+ if (ISDIGIT (*mangled))
+ mangled = dlang_parse_symbol (decl, mangled, dlang_template_ident);
+ else if (strncmp (mangled, "_D", 2) == 0)
+ {
+ mangled += 2;
+ mangled = dlang_parse_symbol (decl, mangled, dlang_function);
+ }
+
+ /* Check for name length mismatch. */
+ if (mangled && (mangled - pend) == psize)
+ return mangled;
+
+ psize /= 10;
+ string_setlength (decl, saved);
+ }
+
+ /* No match on any combinations. */
+ return NULL;
+ }
+ else
+ {
+ if (strlen (endptr) < (size_t) len)
return NULL;

mangled = endptr;

/* May be a template instance. */
- if (i >= 5 && strncmp (mangled, "__T", 3) == 0)
+ if (len >= 5 && strncmp (mangled, "__T", 3) == 0)
{
/* Template symbol. */
if (ISDIGIT (mangled[3]) && mangled[3] != '0')
- return dlang_parse_template (decl, mangled, i);
+ return dlang_parse_template (decl, mangled, len);

return NULL;
}

- if (strncmp (mangled, "__ctor", i) == 0)
- {
- /* Constructor symbol for a class/struct. */
- string_append (decl, "this");
- mangled += i;
- return mangled;
- }
- else if (strncmp (mangled, "__dtor", i) == 0)
- {
- /* Destructor symbol for a class/struct. */
- string_append (decl, "~this");
- mangled += i;
- return mangled;
- }
- else if (strncmp (mangled, "__postblit", i) == 0)
- {
- /* Postblit symbol for a struct. */
- string_append (decl, "this(this)");
- mangled += i;
- return mangled;
- }
- else if (strncmp (mangled, "__initZ", i+1) == 0)
- {
- /* The static initialiser for a given symbol. */
- string_append (decl, "init$");
- mangled += i + 1;
- return mangled;
- }
- else if (strncmp (mangled, "__ClassZ", i+1) == 0)
+ switch (len)
{
- /* The classinfo symbol for a given class. */
- string_prepend (decl, "ClassInfo for ");
- string_setlength (decl, string_length (decl) - 1);
- mangled += i + 1;
- return mangled;
- }
- else if (strncmp (mangled, "__vtblZ", i+1) == 0)
- {
- /* The vtable symbol for a given class. */
- string_prepend (decl, "vtable for ");
- string_setlength (decl, string_length (decl) - 1);
- mangled += i + 1;
- return mangled;
- }
- else if (strncmp (mangled, "__InterfaceZ", i+1) == 0)
- {
- /* The interface symbol for a given class. */
- string_prepend (decl, "Interface for ");
- string_setlength (decl, string_length (decl) - 1);
- mangled += i + 1;
- return mangled;
- }
- else if (strncmp (mangled, "__ModuleInfoZ", i+1) == 0)
- {
- /* The ModuleInfo symbol for a given module. */
- string_prepend (decl, "ModuleInfo for ");
- string_setlength (decl, string_length (decl) - 1);
- mangled += i + 1;
- return mangled;
+ case 6:
+ if (strncmp (mangled, "__ctor", len) == 0)
+ {
+ /* Constructor symbol for a class/struct. */
+ string_append (decl, "this");
+ mangled += len;
+ return mangled;
+ }
+ else if (strncmp (mangled, "__dtor", len) == 0)
+ {
+ /* Destructor symbol for a class/struct. */
+ string_append (decl, "~this");
+ mangled += len;
+ return mangled;
+ }
+ else if (strncmp (mangled, "__initZ", len+1) == 0)
+ {
+ /* The static initialiser for a given symbol. */
+ string_append (decl, "init$");
+ mangled += len;
+ return mangled;
+ }
+ else if (strncmp (mangled, "__vtblZ", len+1) == 0)
+ {
+ /* The vtable symbol for a given class. */
+ string_prepend (decl, "vtable for ");
+ string_setlength (decl, string_length (decl) - 1);
+ mangled += len;
+ return mangled;
+ }
+ break;
+
+ case 7:
+ if (strncmp (mangled, "__ClassZ", len+1) == 0)
+ {
+ /* The classinfo symbol for a given class. */
+ string_prepend (decl, "ClassInfo for ");
+ string_setlength (decl, string_length (decl) - 1);
+ mangled += len;
+ return mangled;
+ }
+ break;
+
+ case 10:
+ if (strncmp (mangled, "__postblitMFZ", len+3) == 0)
+ {
+ /* Postblit symbol for a struct. */
+ string_append (decl, "this(this)");
+ mangled += len + 3;
+ return mangled;
+ }
+ break;
+
+ case 11:
+ if (strncmp (mangled, "__InterfaceZ", len+1) == 0)
+ {
+ /* The interface symbol for a given class. */
+ string_prepend (decl, "Interface for ");
+ string_setlength (decl, string_length (decl) - 1);
+ mangled += len;
+ return mangled;
+ }
+ break;
+
+ case 12:
+ if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0)
+ {
+ /* The ModuleInfo symbol for a given module. */
+ string_prepend (decl, "ModuleInfo for ");
+ string_setlength (decl, string_length (decl) - 1);
+ mangled += len;
+ return mangled;
+ }
+ break;
}

- string_appendn (decl, mangled, i);
- mangled += i;
+ string_appendn (decl, mangled, len);
+ mangled += len;
}
- else
- return NULL;

return mangled;
}
@@ -931,7 +1091,38 @@ dlang_parse_string (string *decl, const char *mangled)
char a = ascii2hex (mangled[0]);
char b = ascii2hex (mangled[1]);
char val = (a << 4) | b;
- string_appendn (decl, &val, 1);
+
+ /* Sanitize white and non-printable characters. */
+ switch (val)
+ {
+ case ' ':
+ string_append (decl, " ");
+ break;
+ case '\t':
+ string_append (decl, "\\t");
+ break;
+ case '\n':
+ string_append (decl, "\\n");
+ break;
+ case '\r':
+ string_append (decl, "\\r");
+ break;
+ case '\f':
+ string_append (decl, "\\f");
+ break;
+ case '\v':
+ string_append (decl, "\\v");
+ break;
+
+ default:
+ if (ISPRINT (val))
+ string_appendn (decl, &val, 1);
+ else
+ {
+ string_append (decl, "\\x");
+ string_appendn (decl, mangled, 2);
+ }
+ }
}
else
return NULL;
@@ -1030,7 +1221,7 @@ static const char *
dlang_value (string *decl, const char *mangled, const char *name, char type)
{
if (mangled == NULL || *mangled == '\0')
- return mangled;
+ return NULL;

switch (*mangled)
{
@@ -1104,28 +1295,54 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
return mangled;
}

+/* Extract the type modifiers from MANGLED and return the string
+ length that it consumes in MANGLED on success or 0 on failure. */
static int
-dlang_call_convention_p (const char *mangled)
+dlang_type_modifier_p (const char *mangled)
{
- size_t i;
+ int i;

switch (*mangled)
{
- case 'F': case 'U': case 'V':
- case 'W': case 'R':
+ case 'x': case 'y':
return 1;

- case 'M': /* Prefix for functions needing 'this' */
- i = 1;
- if (mangled[i] == 'x')
- i++;
+ case 'O':
+ mangled++;
+ i = dlang_type_modifier_p (mangled);
+ return i + 1;

- switch (mangled[i])
+ case 'N':
+ mangled++;
+ if (*mangled == 'g')
{
- case 'F': case 'U': case 'V':
- case 'W': case 'R':
- return 1;
+ mangled++;
+ i = dlang_type_modifier_p (mangled);
+ return i + 2;
}
+ }
+
+ return 0;
+}
+
+/* Extract the function calling convention from MANGLED and
+ return 1 on success or 0 on failure. */
+static int
+dlang_call_convention_p (const char *mangled)
+{
+ /* Prefix for functions needing 'this' */
+ if (*mangled == 'M')
+ {
+ mangled++;
+ /* Also skip over any type modifiers. */
+ mangled += dlang_type_modifier_p (mangled);
+ }
+
+ switch (*mangled)
+ {
+ case 'F': case 'U': case 'V':
+ case 'W': case 'R':
+ return 1;

default:
return 0;
@@ -1135,23 +1352,41 @@ dlang_call_convention_p (const char *mangled)
/* Extract and demangle the symbol in MANGLED and append it to DECL.
Returns the remaining signature on success or NULL on failure. */
static const char *
-dlang_parse_symbol (string *decl, const char *mangled)
+dlang_parse_symbol (string *decl, const char *mangled,
+ enum dlang_symbol_kinds kind)
{
+ int saved;
size_t n = 0;
do
{
if (n++)
string_append (decl, ".");

- mangled = dlang_identifier (decl, mangled);
+ mangled = dlang_identifier (decl, mangled, kind);

if (mangled && dlang_call_convention_p (mangled))
{
- int saved;
+ string mods;
+ const char *start = NULL;
+ int checkpoint = 0;

/* Skip over 'this' parameter. */
if (*mangled == 'M')
- mangled += (mangled[1] == 'x') ? 2 : 1;
+ mangled++;
+
+ /* We have reached here because we expect an extern(Pascal) function.
+ However this is so rare, that it is more likely a template value
+ parameter. Since this can't be assumed, first attempt parsing
+ the symbol as a function, and then back out on failure. */
+ if (*mangled == 'V')
+ {
+ start = mangled;
+ checkpoint = string_length (decl);
+ }
+
+ /* Save the type modifiers for appending at the end. */
+ string_init (&mods);
+ mangled = dlang_type_modifiers (&mods, mangled);

/* Skip over calling convention and attributes in qualified name. */
saved = string_length (decl);
@@ -1163,17 +1398,41 @@ dlang_parse_symbol (string *decl, const char *mangled)
mangled = dlang_function_args (decl, mangled);
string_append (decl, ")");

- /* Demangle the function return type as a kind of sanity test. */
- if (mangled && !ISDIGIT (*mangled))
+ /* Add any const/immutable/shared modifier. */
+ string_appendn (decl, mods.b, string_length (&mods));
+ string_delete (&mods);
+
+ if (mangled == NULL && checkpoint != 0)
{
- saved = string_length (decl);
- mangled = dlang_type (decl, mangled);
- string_setlength (decl, saved);
+ mangled = start;
+ string_setlength (decl, checkpoint);
}
}
}
while (mangled && ISDIGIT (*mangled));

+ /* Only top-level symbols or function template parameters have
+ a type that needs checking. */
+ if (kind == dlang_top_level || kind == dlang_function)
+ {
+ /* Artificial symbols end with 'Z' and have no type. */
+ if (mangled && *mangled == 'Z')
+ mangled++;
+ else
+ {
+ saved = string_length (decl);
+ mangled = dlang_type (decl, mangled);
+ string_setlength (decl, saved);
+ }
+
+ /* Check that the entire symbol was successfully demangled. */
+ if (kind == dlang_top_level)
+ {
+ if (mangled == NULL || *mangled != '\0')
+ return NULL;
+ }
+ }
+
return mangled;
}

@@ -1221,11 +1480,15 @@ dlang_template_args (string *decl, const char *mangled)
if (n++)
string_append (decl, ", ");

+ /* Skip over specialised template prefix. */
+ if (*mangled == 'H')
+ mangled++;
+
switch (*mangled)
{
case 'S': /* Symbol parameter. */
mangled++;
- mangled = dlang_parse_symbol (decl, mangled);
+ mangled = dlang_parse_symbol (decl, mangled, dlang_template_param);
break;
case 'T': /* Type parameter. */
mangled++;
@@ -1283,7 +1546,7 @@ dlang_parse_template (string *decl, const char *mangled, long len)
mangled += 3;

/* Template identifier. */
- mangled = dlang_identifier (decl, mangled);
+ mangled = dlang_identifier (decl, mangled, dlang_template_ident);

/* Template arguments. */
string_append (decl, "!(");
@@ -1322,7 +1585,7 @@ dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
{
mangled += 2;

- if (dlang_parse_symbol (&decl, mangled) == NULL)
+ if (dlang_parse_symbol (&decl, mangled, dlang_top_level) == NULL)
string_delete (&decl);
}

diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 2aeacb8..6c8ccdf 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -114,6 +114,14 @@ _D8demangle4testFwZv
demangle.test(dchar)
#
--format=dlang
+_D8demangle4testFziZv
+demangle.test(cent)
+#
+--format=dlang
+_D8demangle4testFzkZv
+demangle.test(ucent)
+#
+--format=dlang
_D8demangle4testFOaZv
demangle.test(shared(char))
#
@@ -314,6 +322,14 @@ _D8demangle4testFMaZv
demangle.test(scope char)
#
--format=dlang
+_D8demangle4testFNjaZv
+demangle.test(char)
+#
+--format=dlang
+_D8demangle4testFNkaZv
+demangle.test(return char)
+#
+--format=dlang
_D8demangle4testFaXv
demangle.test(char...)
#
@@ -434,6 +450,22 @@ _D8demangle4testFDFNdNfNaZaZv
demangle.test(char() @property @safe pure delegate)
#
--format=dlang
+_D8demangle4testFNjDFZaZv
+demangle.test(char() delegate)
+#
+--format=dlang
+_D8demangle4testFNkDFZaZv
+demangle.test(return char() delegate)
+#
+--format=dlang
+_D8demangle4testFDFNjZaZv
+demangle.test(char() return delegate)
+#
+--format=dlang
+_D8demangle4testFNjNkDFNjZaZv
+demangle.test(return char() return delegate)
+#
+--format=dlang
_D8demangle4testFFNaZaZv
demangle.test(char() pure function)
#
@@ -474,6 +506,22 @@ _D8demangle4testFFNdNfNaZaZv
demangle.test(char() @property @safe pure function)
#
--format=dlang
+_D8demangle4testFNjFZaZv
+demangle.test(char() function)
+#
+--format=dlang
+_D8demangle4testFNkFZaZv
+demangle.test(return char() function)
+#
+--format=dlang
+_D8demangle4testFFNjZaZv
+demangle.test(char() return function)
+#
+--format=dlang
+_D8demangle4testFNjNkFNjZaZv
+demangle.test(return char() return function)
+#
+--format=dlang
_D8demangle4test6__initZ
demangle.test.init$
#
@@ -502,7 +550,7 @@ _D8demangle4test6__dtorMFZv
demangle.test.~this()
#
--format=dlang
-_D8demangle4test6__postblitMFZv
+_D8demangle4test10__postblitMFZv
demangle.test.this(this)
#
--format=dlang
@@ -566,12 +614,12 @@ _D8demangle17__T4testS6symbolZv
demangle.test!(symbol)
#
--format=dlang
-_D8demangle21__T4testS6symbol3fooZv
+_D8demangle23__T4testS116symbol3fooZv
demangle.test!(symbol.foo)
#
--format=dlang
-_D8demangle25__T4testS6symbol3foo3barZv
-demangle.test!(symbol.foo.bar)
+_D8demangle32__T4testS20_D6symbol3foo3barFZvZv
+demangle.test!(symbol.foo.bar())
#
--format=dlang
_D8demangle19__T4testTaS6symbolZv
@@ -582,6 +630,10 @@ _D8demangle19__T4testS6symbolTaZv
demangle.test!(symbol, char)
#
--format=dlang
+_D8demangle12__T4testHTaZv
+demangle.test!(char)
+#
+--format=dlang
_D8demangle13__T4testVPinZv
demangle.test!(null)
#
@@ -753,6 +805,70 @@ demangle.test!(demangle.S(1, 2))
_D8demangle35__T4testVS8demangle1SS2i1a3_616263Zv
demangle.test!(demangle.S(1, "abc"))
#
+--format=dlang
+_D8demangle4testMxFZv
+demangle.test() const
+#
+--format=dlang
+_D8demangle4testMyFZv
+demangle.test() immutable
+#
+--format=dlang
+_D8demangle4testMNgFZv
+demangle.test() inout
+#
+--format=dlang
+_D8demangle4testMNgxFZv
+demangle.test() inout const
+#
+--format=dlang
+_D8demangle4testMOFZv
+demangle.test() shared
+#
+--format=dlang
+_D8demangle4testMOxFZv
+demangle.test() shared const
+#
+--format=dlang
+_D8demangle4testMONgFZv
+demangle.test() shared inout
+#
+--format=dlang
+_D8demangle4testMONgxFZv
+demangle.test() shared inout const
+#
+--format=dlang
+_D8demangle4testFDxFZaZv
+demangle.test(char() delegate const)
+#
+--format=dlang
+_D8demangle4testFDyFZaZv
+demangle.test(char() delegate immutable)
+#
+--format=dlang
+_D8demangle4testFDNgFZaZv
+demangle.test(char() delegate inout)
+#
+--format=dlang
+_D8demangle4testFDNgxFZaZv
+demangle.test(char() delegate inout const)
+#
+--format=dlang
+_D8demangle4testFDOFZaZv
+demangle.test(char() delegate shared)
+#
+--format=dlang
+_D8demangle4testFDOxFZaZv
+demangle.test(char() delegate shared const)
+#
+--format=dlang
+_D8demangle4testFDONgFZaZv
+demangle.test(char() delegate shared inout)
+#
+--format=dlang
+_D8demangle4testFDONgxFZaZv
+demangle.test(char() delegate shared inout const)
+#
# Unittests
#
--format=dlang
@@ -816,19 +932,19 @@ _D6plugin8generateFiiZAOa
plugin.generate(int, int)
#
--format=dlang
-_D8demangle3fnAFZv3fnBMFZv
+_D8demangle3fnAFZ3fnBMFZv
demangle.fnA().fnB()
#
--format=dlang
-_D8demangle4mainFZv1S3fnCFZv
+_D8demangle4mainFZ1S3fnCMFZv
demangle.main().S.fnC()
#
--format=dlang
-_D8demangle4mainFZv1S3fnDMFZv
+_D8demangle4mainFZ1S3fnDMFZv
demangle.main().S.fnD()
#
--format=dlang
-_D8demangle4mainFZv5localMFZi
+_D8demangle4mainFZ5localMFZi
demangle.main().local()
#
--format=dlang
@@ -872,7 +988,7 @@ _D6object14TypeInfo_Array8argTypesMFNbNfJC8TypeInfoJC8TypeInfoZi
object.TypeInfo_Array.argTypes(out TypeInfo, out TypeInfo)
#
--format=dlang
-_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7tryExecMFMDFZvZv
+_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv
rt.dmain2._d_run_main(int, char**, extern(C) int(char[][]) function*).tryExec(scope void() delegate)
#
--format=dlang
@@ -928,9 +1044,37 @@ _D2gc11gctemplates56__T8mkBitmapTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ8mkB
gc.gctemplates.mkBitmap!(std.range.iota!(int, int).iota(int, int).Result).mkBitmap(ulong*, ulong)
#
--format=dlang
-_D8serenity9persister6Sqlite70__T15SqlitePersisterTS8serenity9persister6Sqlite11__unittest6FZv4TestZ15SqlitePersister12__T7opIndexZ7opIndexMFmZS8serenity9persister6Sqlite11__unittest6FZv4Test
+_D8serenity9persister6Sqlite69__T15SqlitePersisterTS8serenity9persister6Sqlite11__unittest6FZ4TestZ15SqlitePersister12__T7opIndexZ7opIndexMFmZS8serenity9persister6Sqlite11__unittest6FZ4Test
serenity.persister.Sqlite.SqlitePersister!(serenity.persister.Sqlite.__unittest6().Test).SqlitePersister.opIndex!().opIndex(ulong)
#
--format=dlang
-_D4test4mainFZv5localMFZi
-test.main().local()
+_D3std6socket12InternetHost221__T13getHostNoSyncVAyaa96_0a09202020206175746f2078203d2068746f6e6c28706172616d293b0a09202020206175746f206865203d20676574686f73746279616464722826782c20342c206361737428696e74294164647265737346616d696c792e494e4554293b0a09TkZ13getHostNoSyncMFkZb
+std.socket.InternetHost.getHostNoSync!("\n\t auto x = htonl(param);\n\t auto he = gethostbyaddr(&x, 4, cast(int)AddressFamily.INET);\n\t", uint).getHostNoSync(uint)
+#
+--format=dlang
+_D2gc6config13__T5parseHTfZ5parseFNbNiAxaKAxaKfZb
+gc.config.parse!(float).parse(const(char)[], ref const(char)[], ref float)
+#
+--format=dlang
+_D3std11parallelism273__T4TaskS213std11parallelism3runTDFS3std9algorithm87__T9MapResultS27_D4test4mainFZ7getTermMFiZeTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ9MapResultmmZeTS3std9algorithm87__T9MapResultS27_D4test4mainFZ7getTermMFiZeTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ9MapResultTmTmZ4Task4implFPvZv
+std.parallelism.Task!(std.parallelism.run, real(std.algorithm.MapResult!(test.main().getTerm(int), std.range.iota!(int, int).iota(int, int).Result).MapResult, ulong, ulong) delegate, std.algorithm.MapResult!(test.main().getTerm(int), std.range.iota!(int, int).iota(int, int).Result).MapResult, ulong, ulong).Task.impl(void*)
+#
+--format=dlang
+_D2rt5minfo16__unittestL518_6FZ12UTModuleInfo6__ctorMFNckZS2rt5minfo16__unittestL518_6FZ12UTModuleInfo
+rt.minfo.__unittestL518_6().UTModuleInfo.this(uint)
+#
+--format=dlang
+_D3std6traits37__T7fqnTypeTC6ObjectVbi0Vbi0Vbi0Vbi0Z13addQualifiersFAyabbbbZAya
+std.traits.fqnType!(Object, false, false, false, false).addQualifiers(immutable(char)[], bool, bool, bool, bool)
+#
+--format=dlang
+_D3std9algorithm117__T9MapResultS153std5range4onlyTS3std9algorithm53__T12FilterResultS28_D3std3uni7isUpperFNaNbNfwZbTAyaZ12FilterResultZ9MapResult5frontMFNaNdNfZS3std5range22__T10OnlyResultTwVmi1Z10OnlyResult
+std.algorithm.MapResult!(std.range.only, std.algorithm.FilterResult!(std.uni.isUpper(dchar), immutable(char)[]).FilterResult).MapResult.front()
+#
+--format=dlang
+_D3std6traits17__T6fqnSymS43stdZ11adjustIdentFAyaZAya
+std.traits.fqnSym!(std).adjustIdent(immutable(char)[])
+#
+--format=dlang
+_D2rt8lifetime36__T14_d_newarrayOpTS13_d_newarrayiTZ14_d_newarrayOpTFNaNbxC8TypeInfomPmZAv
+rt.lifetime._d_newarrayOpT!(_d_newarrayiT)._d_newarrayOpT(const(TypeInfo), ulong, ulong*)