From: Iain Buclaw Date: Tue, 23 Sep 2014 18:36:14 +0000 (+0000) Subject: demangle.h (DMGL_DLANG): New macro. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=43b1b9edfcd5aeb8fe5ca012c81cdd8d4259de04;p=gcc.git demangle.h (DMGL_DLANG): New macro. include/: * demangle.h (DMGL_DLANG): New macro. (DMGL_STYLE_MASK): Add DMGL_DLANG. (demangling_styles): Add dlang_demangling. (DLANG_DEMANGLING_STYLE_STRING): New macro. (DLANG_DEMANGLING): New macro. (dlang_demangle): New prototype. libiberty/: * Makefile.in (CFILES): Add d-demangle.c. (REQUIRED_OFILES): Add d-demangle.o. * cplus-dem.c (libiberty_demanglers): Add dlang_demangling case. (cplus_demangle): Likewise. * d-demangle.c: New file. * testsuite/Makefile.in (really-check): Add check-d-demangle. * testsuite/d-demangle-expected: New file. From-SVN: r215530 --- diff --git a/include/ChangeLog b/include/ChangeLog index a3b6a28b947..88176beda19 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,12 @@ +2014-09-23 Iain Buclaw + + * demangle.h (DMGL_DLANG): New macro. + (DMGL_STYLE_MASK): Add DMGL_DLANG. + (demangling_styles): Add dlang_demangling. + (DLANG_DEMANGLING_STYLE_STRING): New macro. + (DLANG_DEMANGLING): New macro. + (dlang_demangle): New prototype. + 2014-09-15 Andreas Krebbel * longlong.h: Add __udiv_w_sdiv prototype. diff --git a/include/demangle.h b/include/demangle.h index bbad71bd8c7..d2a6731a9ee 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -63,9 +63,10 @@ extern "C" { #define DMGL_EDG (1 << 13) #define DMGL_GNU_V3 (1 << 14) #define DMGL_GNAT (1 << 15) +#define DMGL_DLANG (1 << 16) /* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT) +#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG) /* Enumeration of possible demangling styles. @@ -87,7 +88,8 @@ extern enum demangling_styles edg_demangling = DMGL_EDG, gnu_v3_demangling = DMGL_GNU_V3, java_demangling = DMGL_JAVA, - gnat_demangling = DMGL_GNAT + gnat_demangling = DMGL_GNAT, + dlang_demangling = DMGL_DLANG } current_demangling_style; /* Define string names for the various demangling styles. */ @@ -102,6 +104,7 @@ extern enum demangling_styles #define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3" #define JAVA_DEMANGLING_STYLE_STRING "java" #define GNAT_DEMANGLING_STYLE_STRING "gnat" +#define DLANG_DEMANGLING_STYLE_STRING "dlang" /* Some macros to test what demangling style is active. */ @@ -115,6 +118,7 @@ extern enum demangling_styles #define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3) #define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA) #define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT) +#define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG) /* Provide information about the available demangle styles. This code is pulled from gdb into libiberty because it is useful to binutils also. */ @@ -169,6 +173,9 @@ java_demangle_v3 (const char *mangled); char * ada_demangle (const char *mangled, int options); +extern char * +dlang_demangle (const char *mangled, int options); + enum gnu_v3_ctor_kinds { gnu_v3_complete_object_ctor = 1, gnu_v3_base_object_ctor, diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 3845433378b..d47b8730ea5 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,13 @@ +2014-09-23 Iain Buclaw + + * Makefile.in (CFILES): Add d-demangle.c. + (REQUIRED_OFILES): Add d-demangle.o. + * cplus-dem.c (libiberty_demanglers): Add dlang_demangling case. + (cplus_demangle): Likewise. + * d-demangle.c: New file. + * testsuite/Makefile.in (really-check): Add check-d-demangle. + * testsuite/d-demangle-expected: New file. + 2014-09-19 Ian Lance Taylor * simple-object-elf.c (simple_object_elf_write_ehdr): Correctly diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 44e340f721c..9b877209bd1 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -127,7 +127,7 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \ basename.c bcmp.c bcopy.c bsearch.c bzero.c \ calloc.c choose-temp.c clock.c concat.c cp-demangle.c \ cp-demint.c cplus-dem.c crc32.c \ - dwarfnames.c dyn-string.c \ + d-demangle.c dwarfnames.c dyn-string.c \ fdmatch.c ffs.c fibheap.c filename_cmp.c floatformat.c \ fnmatch.c fopen_unlocked.c \ getcwd.c getopt.c getopt1.c getpagesize.c getpwd.c getruntime.c \ @@ -167,7 +167,7 @@ REQUIRED_OFILES = \ ./md5.$(objext) ./sha1.$(objext) ./alloca.$(objext) \ ./argv.$(objext) \ ./choose-temp.$(objext) ./concat.$(objext) \ - ./cp-demint.$(objext) ./crc32.$(objext) \ + ./cp-demint.$(objext) ./crc32.$(objext) ./d-demangle.$(objext) \ ./dwarfnames.$(objext) ./dyn-string.$(objext) \ ./fdmatch.$(objext) ./fibheap.$(objext) \ ./filename_cmp.$(objext) ./floatformat.$(objext) \ @@ -714,6 +714,14 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir else true; fi $(COMPILE.c) $(srcdir)/dyn-string.c $(OUTPUT_OPTION) +./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \ + $(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \ + $(INCDIR)/dyn-string.h $(INCDIR)/getopt.h $(INCDIR)/libiberty.h + if [ x"$(PICFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \ + else true; fi + $(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION) + ./fdmatch.$(objext): $(srcdir)/fdmatch.c config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/libiberty.h if [ x"$(PICFLAG)" != x ]; then \ diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index 52767cc8fde..c68b9813de2 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -305,6 +305,12 @@ const struct demangler_engine libiberty_demanglers[] = "GNAT style demangling" } , + { + DLANG_DEMANGLING_STYLE_STRING, + dlang_demangling, + "DLANG style demangling" + } + , { NULL, unknown_demangling, NULL } @@ -870,6 +876,13 @@ cplus_demangle (const char *mangled, int options) if (GNAT_DEMANGLING) return ada_demangle (mangled, options); + if (DLANG_DEMANGLING) + { + ret = dlang_demangle (mangled, options); + if (ret) + return ret; + } + ret = internal_cplus_demangle (work, mangled); squangle_mop_up (work); return (ret); diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c new file mode 100644 index 00000000000..d31bf942378 --- /dev/null +++ b/libiberty/d-demangle.c @@ -0,0 +1,1338 @@ +/* Demangler for the D programming language + Copyright 2014 Free Software Foundation, Inc. + Written by Iain Buclaw (ibuclaw@gdcproject.org) + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +In addition to the permissions in the GNU Library General Public +License, the Free Software Foundation gives you unlimited permission +to link the compiled version of this file into combinations with other +programs, and to distribute those combinations without any restriction +coming from the use of this file. (The Library Public License +restrictions do apply in other respects; for example, they cover +modification of the file, and distribution when not linked into a +combined executable.) + +Libiberty is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. +If not, see . */ + +/* This file exports one function; dlang_demangle. + + This file imports strtol and strtold for decoding mangled literals. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "safe-ctype.h" + +#include +#include +#include + +#ifdef HAVE_STDLIB_H +#include +#else +extern long strtol (const char *nptr, char **endptr, int base); +extern long double strtold (const char *nptr, char **endptr); +#endif + +#include +#include "libiberty.h" + +/* A mini string-handling package */ + +typedef struct string /* Beware: these aren't required to be */ +{ /* '\0' terminated. */ + char *b; /* pointer to start of string */ + char *p; /* pointer after last character */ + char *e; /* pointer after end of allocated space */ +} string; + +static void +string_need (string *s, int n) +{ + int tem; + + if (s->b == NULL) + { + if (n < 32) + { + n = 32; + } + s->p = s->b = XNEWVEC (char, n); + s->e = s->b + n; + } + else if (s->e - s->p < n) + { + tem = s->p - s->b; + n += tem; + n *= 2; + s->b = XRESIZEVEC (char, s->b, n); + s->p = s->b + tem; + s->e = s->b + n; + } +} + +static void +string_delete (string *s) +{ + if (s->b != NULL) + { + XDELETEVEC (s->b); + s->b = s->e = s->p = NULL; + } +} + +static void +string_init (string *s) +{ + s->b = s->p = s->e = NULL; +} + +static int +string_length (string *s) +{ + if (s->p == s->b) + { + return 0; + } + return s->p - s->b; +} + +static void +string_setlength (string *s, int n) +{ + if (n - string_length (s) < 0) + { + s->p = s->b + n; + } +} + +static void +string_append (string *p, const char *s) +{ + int n = strlen (s); + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; +} + +static void +string_appendn (string *p, const char *s, int n) +{ + if (n != 0) + { + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; + } +} + +static void +string_prependn (string *p, const char *s, int n) +{ + char *q; + + if (n != 0) + { + string_need (p, n); + for (q = p->p - 1; q >= p->b; q--) + { + q[n] = q[0]; + } + memcpy (p->b, s, n); + p->p += n; + } +} + +static void +string_prepend (string *p, const char *s) +{ + if (s != NULL && *s != '\0') + { + string_prependn (p, s, strlen (s)); + } +} + +/* Prototypes for forward referenced functions */ +static const char *dlang_function_args (string *, const char *); + +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_tuple (string *, const char *); + +static const char *dlang_parse_template (string *, const char *, long); + + +/* Demangle the calling convention from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_call_convention (string *decl, const char *mangled) +{ + if (mangled == NULL || *mangled == '\0') + return mangled; + + switch (*mangled) + { + case 'F': /* (D) */ + mangled++; + break; + case 'U': /* (C) */ + mangled++; + string_append (decl, "extern(C) "); + break; + case 'W': /* (Windows) */ + mangled++; + string_append (decl, "extern(Windows) "); + break; + case 'V': /* (Pascal) */ + mangled++; + string_append (decl, "extern(Pascal) "); + break; + case 'R': /* (C++) */ + mangled++; + string_append (decl, "extern(C++) "); + break; + default: + return NULL; + } + + 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; + + while (*mangled == 'N') + { + mangled++; + switch (*mangled) + { + case 'a': /* pure */ + mangled++; + string_append (decl, "pure "); + continue; + case 'b': /* nothrow */ + mangled++; + string_append (decl, "nothrow "); + continue; + case 'c': /* ref */ + mangled++; + string_append (decl, "ref "); + continue; + case 'd': /* @property */ + mangled++; + string_append (decl, "@property "); + continue; + case 'e': /* @trusted */ + mangled++; + string_append (decl, "@trusted "); + continue; + case 'f': /* @safe */ + mangled++; + string_append (decl, "@safe "); + continue; + case 'g': + case 'h': + /* inout parameter is represented as 'Ng'. + vector parameter is represented as 'Nh'. + If we see this, then we know we're really in the + parameter list. Rewind and break. */ + mangled--; + break; + case 'i': /* @nogc */ + mangled++; + string_append (decl, "@nogc "); + continue; + } + break; + } + + return mangled; +} + +/* Demangle the function type from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_function_type (string *decl, const char *mangled) +{ + string attr, args, type; + size_t szattr, szargs, sztype; + + if (mangled == NULL || *mangled == '\0') + return mangled; + + /* The order of the mangled string is: + CallConvention FuncAttrs Arguments ArgClose Type + + The demangled string is re-ordered as: + CallConvention Type Arguments FuncAttrs + */ + string_init (&attr); + string_init (&args); + string_init (&type); + + /* Function call convention. */ + mangled = dlang_call_convention (decl, mangled); + + /* Function attributes. */ + mangled = dlang_attributes (&attr, mangled); + szattr = string_length (&attr); + + /* Function arguments. */ + mangled = dlang_function_args (&args, mangled); + szargs = string_length (&args); + + /* Function return type. */ + mangled = dlang_type (&type, mangled); + sztype = string_length (&type); + + /* Append to decl in order. */ + string_appendn (decl, type.b, sztype); + string_append (decl, "("); + string_appendn (decl, args.b, szargs); + string_append (decl, ") "); + string_appendn (decl, attr.b, szattr); + + string_delete (&attr); + string_delete (&args); + string_delete (&type); + return mangled; +} + +/* Demangle the argument list from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_function_args (string *decl, const char *mangled) +{ + size_t n = 0; + + while (mangled && *mangled != '\0') + { + switch (*mangled) + { + case 'X': /* (variadic T t...) style. */ + mangled++; + string_append (decl, "..."); + return mangled; + case 'Y': /* (variadic T t, ...) style. */ + mangled++; + string_append (decl, ", ..."); + return mangled; + case 'Z': /* Normal function. */ + mangled++; + return mangled; + } + + if (n++) + string_append (decl, ", "); + + if (*mangled == 'M') /* scope(T) */ + { + mangled++; + string_append (decl, "scope "); + } + + switch (*mangled) + { + case 'J': /* out(T) */ + mangled++; + string_append (decl, "out "); + break; + case 'K': /* ref(T) */ + mangled++; + string_append (decl, "ref "); + break; + case 'L': /* lazy(T) */ + mangled++; + string_append (decl, "lazy "); + break; + } + mangled = dlang_type (decl, mangled); + } + + return mangled; +} + +/* Demangle the type from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_type (string *decl, const char *mangled) +{ + if (mangled == NULL || *mangled == '\0') + return mangled; + + switch (*mangled) + { + case 'O': /* shared(T) */ + mangled++; + string_append (decl, "shared("); + mangled = dlang_type (decl, mangled); + string_append (decl, ")"); + return mangled; + case 'x': /* const(T) */ + mangled++; + string_append (decl, "const("); + mangled = dlang_type (decl, mangled); + string_append (decl, ")"); + return mangled; + case 'y': /* immutable(T) */ + mangled++; + string_append (decl, "immutable("); + mangled = dlang_type (decl, mangled); + string_append (decl, ")"); + return mangled; + case 'N': + mangled++; + if (*mangled == 'g') /* wild(T) */ + { + mangled++; + string_append (decl, "inout("); + mangled = dlang_type (decl, mangled); + string_append (decl, ")"); + return mangled; + } + else if (*mangled == 'h') /* vector(T) */ + { + mangled++; + string_append (decl, "__vector("); + mangled = dlang_type (decl, mangled); + string_append (decl, ")"); + return mangled; + } + else + return NULL; + case 'A': /* dynamic array (T[]) */ + mangled++; + mangled = dlang_type (decl, mangled); + string_append (decl, "[]"); + return mangled; + case 'G': /* static array (T[N]) */ + { + const char *numptr; + size_t num = 0; + mangled++; + + numptr = mangled; + while (ISDIGIT (*mangled)) + { + num++; + mangled++; + } + mangled = dlang_type (decl, mangled); + string_append (decl, "["); + string_appendn (decl, numptr, num); + string_append (decl, "]"); + return mangled; + } + case 'H': /* associative array (T[T]) */ + { + string type; + size_t sztype; + mangled++; + + string_init (&type); + mangled = dlang_type (&type, mangled); + sztype = string_length (&type); + + mangled = dlang_type (decl, mangled); + string_append (decl, "["); + string_appendn (decl, type.b, sztype); + string_append (decl, "]"); + + string_delete (&type); + return mangled; + } + case 'P': /* pointer (T*) */ + mangled++; + mangled = dlang_type (decl, mangled); + string_append (decl, "*"); + return mangled; + case 'I': /* ident T */ + case 'C': /* class T */ + case 'S': /* struct T */ + case 'E': /* enum T */ + case 'T': /* typedef T */ + mangled++; + return dlang_parse_symbol (decl, mangled); + case 'D': /* delegate T */ + mangled++; + mangled = dlang_function_type (decl, mangled); + string_append (decl, "delegate"); + return mangled; + case 'B': /* tuple T */ + mangled++; + return dlang_parse_tuple (decl, mangled); + + /* Function types */ + case 'F': case 'U': case 'W': + case 'V': case 'R': + mangled = dlang_function_type (decl, mangled); + string_append (decl, "function"); + return mangled; + + /* Basic types */ + case 'n': + mangled++; + string_append (decl, "none"); + return mangled; + case 'v': + mangled++; + string_append (decl, "void"); + return mangled; + case 'g': + mangled++; + string_append (decl, "byte"); + return mangled; + case 'h': + mangled++; + string_append (decl, "ubyte"); + return mangled; + case 's': + mangled++; + string_append (decl, "short"); + return mangled; + case 't': + mangled++; + string_append (decl, "ushort"); + return mangled; + case 'i': + mangled++; + string_append (decl, "int"); + return mangled; + case 'k': + mangled++; + string_append (decl, "uint"); + return mangled; + case 'l': + mangled++; + string_append (decl, "long"); + return mangled; + case 'm': + mangled++; + string_append (decl, "ulong"); + return mangled; + case 'f': + mangled++; + string_append (decl, "float"); + return mangled; + case 'd': + mangled++; + string_append (decl, "double"); + return mangled; + case 'e': + mangled++; + string_append (decl, "real"); + return mangled; + + /* Imaginary and Complex types */ + case 'o': + mangled++; + string_append (decl, "ifloat"); + return mangled; + case 'p': + mangled++; + string_append (decl, "idouble"); + return mangled; + case 'j': + mangled++; + string_append (decl, "ireal"); + return mangled; + case 'q': + mangled++; + string_append (decl, "cfloat"); + return mangled; + case 'r': + mangled++; + string_append (decl, "cdouble"); + return mangled; + case 'c': + mangled++; + string_append (decl, "creal"); + return mangled; + + /* Other types */ + case 'b': + mangled++; + string_append (decl, "bool"); + return mangled; + case 'a': + mangled++; + string_append (decl, "char"); + return mangled; + case 'u': + mangled++; + string_append (decl, "wchar"); + return mangled; + case 'w': + mangled++; + string_append (decl, "dchar"); + return mangled; + + default: /* unhandled */ + return NULL; + } +} + +/* 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) +{ + if (mangled == NULL || *mangled == '\0') + return mangled; + + if (ISDIGIT (*mangled)) + { + char *endptr; + long i = strtol (mangled, &endptr, 10); + + if (endptr == NULL || i <= 0 || strlen (endptr) < (size_t) i) + return NULL; + + mangled = endptr; + + /* May be a template instance. */ + if (i >= 5 && strncmp (mangled, "__T", 3) == 0) + { + /* Template symbol. */ + if (ISDIGIT (mangled[3]) && mangled[3] != '0') + return dlang_parse_template (decl, mangled, i); + + 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) + { + /* 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; + } + + string_appendn (decl, mangled, i); + mangled += i; + } + else + return NULL; + + return mangled; +} + +/* Extract the integer value from MANGLED and append it to DECL, + where TYPE is the type it should be represented as. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_parse_integer (string *decl, const char *mangled, char type) +{ + if (type == 'a' || type == 'u' || type == 'w') + { + /* Parse character value. */ + char value[10]; + int pos = 10; + int width = 0; + char *endptr; + long val = strtol (mangled, &endptr, 10); + + if (endptr == NULL || val < 0) + return NULL; + + string_append (decl, "'"); + + if (type == 'a' && val >= 0x20 && val < 0x7F) + { + /* Represent as a character literal. */ + char c = (char) val; + string_appendn (decl, &c, 1); + } + else + { + /* Represent as a hexadecimal value. */ + switch (type) + { + case 'a': /* char */ + string_append (decl, "\\x"); + width = 2; + break; + case 'u': /* wchar */ + string_append (decl, "\\u"); + width = 4; + break; + case 'w': /* dchar */ + string_append (decl, "\\U"); + width = 8; + break; + } + + while (val > 0) + { + int digit = val % 16; + + if (digit < 10) + value[--pos] = (char)(digit + '0'); + else + value[--pos] = (char)((digit - 10) + 'a'); + + val /= 16; + width--; + } + + for (; width > 0; width--) + value[--pos] = '0'; + + string_appendn (decl, &(value[pos]), 10 - pos); + } + string_append (decl, "'"); + mangled = endptr; + } + else if (type == 'b') + { + /* Parse boolean value. */ + char *endptr; + long val = strtol (mangled, &endptr, 10); + + if (endptr == NULL || val < 0) + return NULL; + + string_append (decl, val ? "true" : "false"); + mangled = endptr; + } + else + { + /* Parse integer value. */ + const char *numptr = mangled; + size_t num = 0; + + while (ISDIGIT (*mangled)) + { + num++; + mangled++; + } + string_appendn (decl, numptr, num); + + /* Append suffix. */ + switch (type) + { + case 'h': /* ubyte */ + case 't': /* ushort */ + case 'k': /* uint */ + string_append (decl, "u"); + break; + case 'l': /* long */ + string_append (decl, "L"); + break; + case 'm': /* ulong */ + string_append (decl, "uL"); + break; + } + } + + return mangled; +} + +/* Extract the floating-point value from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_parse_real (string *decl, const char *mangled) +{ + char buffer[64]; + int len = 0; + long double value; + char *endptr; + + /* Handle NAN and +-INF. */ + if (strncmp (mangled, "NAN", 3) == 0) + { + string_append (decl, "NaN"); + mangled += 3; + return mangled; + } + else if (strncmp (mangled, "INF", 3) == 0) + { + string_append (decl, "Inf"); + mangled += 3; + return mangled; + } + else if (strncmp (mangled, "NINF", 4) == 0) + { + string_append (decl, "-Inf"); + mangled += 4; + return mangled; + } + + /* Hexadecimal prefix and leading bit. */ + if (*mangled == 'N') + { + buffer[len++] = '-'; + mangled++; + } + + if (!ISXDIGIT (*mangled)) + return NULL; + + buffer[len++] = '0'; + buffer[len++] = 'x'; + buffer[len++] = *mangled; + buffer[len++] = '.'; + mangled++; + + /* Significand. */ + while (ISXDIGIT (*mangled)) + { + buffer[len++] = *mangled; + mangled++; + } + + /* Exponent. */ + if (*mangled != 'P') + return NULL; + + buffer[len++] = 'p'; + mangled++; + + if (*mangled == 'N') + { + buffer[len++] = '-'; + mangled++; + } + + while (ISDIGIT (*mangled)) + { + buffer[len++] = *mangled; + mangled++; + } + + /* Convert buffer from hexadecimal to floating-point. */ + buffer[len] = '\0'; + value = strtold (buffer, &endptr); + + if (endptr == NULL || endptr != (buffer + len)) + return NULL; + + len = snprintf (buffer, sizeof(buffer), "%#Lg", value); + string_appendn (decl, buffer, len); + return mangled; +} + +/* Convert VAL from an ascii hexdigit to value. */ +static char +ascii2hex (char val) +{ + if (val >= 'a' && val <= 'f') + return (val - 'a' + 10); + + if (val >= 'A' && val <= 'F') + return (val - 'A' + 10); + + if (val >= '0' && val <= '9') + return (val - '0'); + + return 0; +} + +/* Extract the string value from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_parse_string (string *decl, const char *mangled) +{ + char type = *mangled; + char *endptr; + long len; + + mangled++; + len = strtol (mangled, &endptr, 10); + + if (endptr == NULL || len < 0) + return NULL; + + mangled = endptr; + if (*mangled != '_') + return NULL; + + mangled++; + string_append (decl, "\""); + while (len--) + { + if (ISXDIGIT (mangled[0]) && ISXDIGIT (mangled[1])) + { + char a = ascii2hex (mangled[0]); + char b = ascii2hex (mangled[1]); + char val = (a << 4) | b; + string_appendn (decl, &val, 1); + } + else + return NULL; + + mangled += 2; + } + string_append (decl, "\""); + + if (type != 'a') + string_appendn (decl, &type, 1); + + return 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) +{ + char *endptr; + long elements = strtol (mangled, &endptr, 10); + + if (endptr == NULL || elements < 0) + return NULL; + + mangled = endptr; + string_append (decl, "["); + while (elements--) + { + mangled = dlang_value (decl, mangled, NULL, '\0'); + if (elements != 0) + string_append (decl, ", "); + } + + string_append (decl, "]"); + return 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) +{ + char *endptr; + long elements = strtol (mangled, &endptr, 10); + + if (endptr == NULL || elements < 0) + return NULL; + + mangled = endptr; + string_append (decl, "["); + while (elements--) + { + mangled = dlang_value (decl, mangled, NULL, '\0'); + string_append (decl, ":"); + mangled = dlang_value (decl, mangled, NULL, '\0'); + + if (elements != 0) + string_append (decl, ", "); + } + + string_append (decl, "]"); + return 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) +{ + char *endptr; + long args = strtol (mangled, &endptr, 10); + + if (endptr == NULL || args < 0) + return NULL; + + mangled = endptr; + if (name != NULL) + string_append (decl, name); + + string_append (decl, "("); + while (args--) + { + mangled = dlang_value (decl, mangled, NULL, '\0'); + if (args != 0) + string_append (decl, ", "); + } + + string_append (decl, ")"); + return mangled; +} + +/* 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) +{ + if (mangled == NULL || *mangled == '\0') + return mangled; + + switch (*mangled) + { + /* Null value. */ + case 'n': + mangled++; + string_append (decl, "null"); + break; + + /* Integral values. */ + case 'N': + mangled++; + string_append (decl, "-"); + mangled = dlang_parse_integer (decl, mangled, type); + break; + + case 'i': + mangled++; + if (*mangled < '0' || *mangled > '9') + return NULL; + /* Fall through */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + mangled = dlang_parse_integer (decl, mangled, type); + break; + + /* Real value. */ + case 'e': + mangled++; + mangled = dlang_parse_real (decl, mangled); + break; + + /* Complex value. */ + case 'c': + mangled++; + mangled = dlang_parse_real (decl, mangled); + string_append (decl, "+"); + if (mangled == NULL || *mangled != 'c') + return NULL; + mangled++; + mangled = dlang_parse_real (decl, mangled); + string_append (decl, "i"); + break; + + /* String values. */ + case 'a': /* UTF8 */ + case 'w': /* UTF16 */ + case 'd': /* UTF32 */ + mangled = dlang_parse_string (decl, mangled); + break; + + /* Array values. */ + case 'A': + mangled++; + if (type == 'H') + mangled = dlang_parse_assocarray (decl, mangled); + else + mangled = dlang_parse_arrayliteral (decl, mangled); + break; + + /* Struct values. */ + case 'S': + mangled++; + mangled = dlang_parse_structlit (decl, mangled, name); + break; + + default: + return NULL; + } + + return mangled; +} + +static int +dlang_call_convention_p (const char *mangled) +{ + size_t i; + + switch (*mangled) + { + case 'F': case 'U': case 'V': + case 'W': case 'R': + return 1; + + case 'M': /* Prefix for functions needing 'this' */ + i = 1; + if (mangled[i] == 'x') + i++; + + switch (mangled[i]) + { + case 'F': case 'U': case 'V': + case 'W': case 'R': + return 1; + } + + default: + return 0; + } +} + +/* 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) +{ + size_t n = 0; + do + { + if (n++) + string_append (decl, "."); + + mangled = dlang_identifier (decl, mangled); + + if (mangled && dlang_call_convention_p (mangled)) + { + int saved; + + /* Skip over 'this' parameter. */ + if (*mangled == 'M') + mangled += (mangled[1] == 'x') ? 2 : 1; + + /* Skip over calling convention and attributes in qualified name. */ + saved = string_length (decl); + mangled = dlang_call_convention (decl, mangled); + mangled = dlang_attributes (decl, mangled); + string_setlength (decl, saved); + + string_append (decl, "("); + mangled = dlang_function_args (decl, mangled); + string_append (decl, ")"); + + /* Demangle the function return type as a kind of sanity test. */ + if (mangled && !ISDIGIT (*mangled)) + { + saved = string_length (decl); + mangled = dlang_type (decl, mangled); + string_setlength (decl, saved); + } + } + } + while (mangled && ISDIGIT (*mangled)); + + return mangled; +} + +/* Demangle the tuple from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_parse_tuple (string *decl, const char *mangled) +{ + char *endptr; + long elements = strtol (mangled, &endptr, 10); + + if (endptr == NULL || elements < 0) + return NULL; + + mangled = endptr; + string_append (decl, "Tuple!("); + + while (elements--) + { + mangled = dlang_type (decl, mangled); + if (elements != 0) + string_append (decl, ", "); + } + + string_append (decl, ")"); + return mangled; +} + +/* Demangle the argument list from MANGLED and append it to DECL. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_template_args (string *decl, const char *mangled) +{ + size_t n = 0; + + while (mangled && *mangled != '\0') + { + switch (*mangled) + { + case 'Z': /* End of parameter list. */ + mangled++; + return mangled; + } + + if (n++) + string_append (decl, ", "); + + switch (*mangled) + { + case 'S': /* Symbol parameter. */ + mangled++; + mangled = dlang_parse_symbol (decl, mangled); + break; + case 'T': /* Type parameter. */ + mangled++; + mangled = dlang_type (decl, mangled); + break; + case 'V': /* Value parameter. */ + { + string name; + char type; + + /* Peek at the type. */ + mangled++; + type = *mangled; + + /* In the few instances where the type is actually desired in + the output, it should precede the value from dlang_value. */ + string_init (&name); + mangled = dlang_type (&name, mangled); + string_need (&name, 1); + *(name.p) = '\0'; + + mangled = dlang_value (decl, mangled, name.b, type); + string_delete (&name); + break; + } + + default: + return NULL; + } + } + + return mangled; +} + +/* Extract and demangle the template symbol in MANGLED, expected to + be made up of LEN characters, and append it to DECL. + Returns the remaining signature on success or NULL on failure. */ +static const char * +dlang_parse_template (string *decl, const char *mangled, long len) +{ + const char *start = mangled; + + /* Template instance names have the types and values of its parameters + encoded into it. + + TemplateInstanceName: + Number __T LName TemplateArgs Z + ^ + The start pointer should be at the above location, and LEN should be + the value of the decoded number. + */ + if (strncmp (mangled, "__T", 3) != 0) + return NULL; + + mangled += 3; + + /* Template identifier. */ + mangled = dlang_identifier (decl, mangled); + + /* Template arguments. */ + string_append (decl, "!("); + mangled = dlang_template_args (decl, mangled); + string_append (decl, ")"); + + /* Check for template name length mismatch. */ + if (mangled && (mangled - start) != len) + return NULL; + + return mangled; +} + +/* Extract and demangle the symbol in MANGLED. Returns the demangled + signature on success or NULL on failure. */ + +char * +dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) +{ + string decl; + char *demangled = NULL; + + if (mangled == NULL || *mangled == '\0') + return NULL; + + if (strncmp (mangled, "_D", 2) != 0) + return NULL; + + string_init (&decl); + + if (strcmp (mangled, "_Dmain") == 0) + { + string_append (&decl, "D main"); + } + else + { + mangled += 2; + + if (dlang_parse_symbol (&decl, mangled) == NULL) + string_delete (&decl); + } + + if (string_length (&decl) > 0) + { + string_need (&decl, 1); + *(decl.p) = '\0'; + demangled = decl.b; + } + + return demangled; +} + diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in index d23c09c8b2d..bb2db67fb66 100644 --- a/libiberty/testsuite/Makefile.in +++ b/libiberty/testsuite/Makefile.in @@ -45,12 +45,15 @@ all: # CHECK is set to "really_check" or the empty string by configure. check: @CHECK@ -really-check: check-cplus-dem check-pexecute check-expandargv +really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv # Run some tests of the demangler. check-cplus-dem: test-demangle $(srcdir)/demangle-expected ./test-demangle < $(srcdir)/demangle-expected +check-d-demangle: test-demangle $(srcdir)/d-demangle-expected + ./test-demangle < $(srcdir)/d-demangle-expected + # Check the pexecute code. check-pexecute: test-pexecute ./test-pexecute diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected new file mode 100644 index 00000000000..2aeacb8389f --- /dev/null +++ b/libiberty/testsuite/d-demangle-expected @@ -0,0 +1,936 @@ +# This file holds test cases for the D demangler. +# Each test case looks like this: +# options +# input to be demangled +# expected output +# +# See demangle-expected for documentation of supported options. +# +# A line starting with `#' is ignored. +# However, blank lines in this file are NOT ignored. +# +############ +# +# Coverage Tests +# +--format=dlang +_Dmain +D main +# +--format=dlang +_D8demangle4testPFLAiYi +demangle.test +# +--format=dlang +_D8demangle4testFaZv +demangle.test(char) +# +--format=dlang +_D8demangle4testFbZv +demangle.test(bool) +# +--format=dlang +_D8demangle4testFcZv +demangle.test(creal) +# +--format=dlang +_D8demangle4testFdZv +demangle.test(double) +# +--format=dlang +_D8demangle4testFeZv +demangle.test(real) +# +--format=dlang +_D8demangle4testFfZv +demangle.test(float) +# +--format=dlang +_D8demangle4testFgZv +demangle.test(byte) +# +--format=dlang +_D8demangle4testFhZv +demangle.test(ubyte) +# +--format=dlang +_D8demangle4testFiZv +demangle.test(int) +# +--format=dlang +_D8demangle4testFjZv +demangle.test(ireal) +# +--format=dlang +_D8demangle4testFkZv +demangle.test(uint) +# +--format=dlang +_D8demangle4testFlZv +demangle.test(long) +# +--format=dlang +_D8demangle4testFmZv +demangle.test(ulong) +# +--format=dlang +_D8demangle4testFnZv +demangle.test(none) +# +--format=dlang +_D8demangle4testFoZv +demangle.test(ifloat) +# +--format=dlang +_D8demangle4testFpZv +demangle.test(idouble) +# +--format=dlang +_D8demangle4testFqZv +demangle.test(cfloat) +# +--format=dlang +_D8demangle4testFrZv +demangle.test(cdouble) +# +--format=dlang +_D8demangle4testFsZv +demangle.test(short) +# +--format=dlang +_D8demangle4testFtZv +demangle.test(ushort) +# +--format=dlang +_D8demangle4testFuZv +demangle.test(wchar) +# +--format=dlang +_D8demangle4testFvZv +demangle.test(void) +# +--format=dlang +_D8demangle4testFwZv +demangle.test(dchar) +# +--format=dlang +_D8demangle4testFOaZv +demangle.test(shared(char)) +# +--format=dlang +_D8demangle4testFxaZv +demangle.test(const(char)) +# +--format=dlang +_D8demangle4testFyaZv +demangle.test(immutable(char)) +# +--format=dlang +_D8demangle4testFNgaZv +demangle.test(inout(char)) +# +--format=dlang +_D8demangle4testFOxaZv +demangle.test(shared(const(char))) +# +--format=dlang +_D8demangle4testFONgaZv +demangle.test(shared(inout(char))) +# +--format=dlang +_D8demangle4testFAaZv +demangle.test(char[]) +# +--format=dlang +_D8demangle4testFAAaZv +demangle.test(char[][]) +# +--format=dlang +_D8demangle4testFAAAaZv +demangle.test(char[][][]) +# +--format=dlang +_D8demangle4testFG42aZv +demangle.test(char[42]) +# +--format=dlang +_D8demangle4testFG42G42aZv +demangle.test(char[42][42]) +# +--format=dlang +_D8demangle4testFG42G42G42aZv +demangle.test(char[42][42][42]) +# +--format=dlang +_D8demangle4testFG1234567890aZv +demangle.test(char[1234567890]) +# +--format=dlang +_D8demangle4testFHaaZv +demangle.test(char[char]) +# +--format=dlang +_D8demangle4testFHHaaaZv +demangle.test(char[char[char]]) +# +--format=dlang +_D8demangle4testFPaZv +demangle.test(char*) +# +--format=dlang +_D8demangle4testFPPaZv +demangle.test(char**) +# +--format=dlang +_D8demangle4testFPPPaZv +demangle.test(char***) +# +--format=dlang +_D8demangle4testFNhG8gZv +demangle.test(__vector(byte[8])) +# +--format=dlang +_D8demangle4testFNhG16gZv +demangle.test(__vector(byte[16])) +# +--format=dlang +_D8demangle4testFNhG32gZv +demangle.test(__vector(byte[32])) +# +--format=dlang +_D8demangle4testFNhG4sZv +demangle.test(__vector(short[4])) +# +--format=dlang +_D8demangle4testFNhG8sZv +demangle.test(__vector(short[8])) +# +--format=dlang +_D8demangle4testFNhG16sZv +demangle.test(__vector(short[16])) +# +--format=dlang +_D8demangle4testFNhG2iZv +demangle.test(__vector(int[2])) +# +--format=dlang +_D8demangle4testFNhG4iZv +demangle.test(__vector(int[4])) +# +--format=dlang +_D8demangle4testFNhG8iZv +demangle.test(__vector(int[8])) +# +--format=dlang +_D8demangle4testFNhG1lZv +demangle.test(__vector(long[1])) +# +--format=dlang +_D8demangle4testFNhG2lZv +demangle.test(__vector(long[2])) +# +--format=dlang +_D8demangle4testFNhG4lZv +demangle.test(__vector(long[4])) +# +--format=dlang +_D8demangle4testFNhG2fZv +demangle.test(__vector(float[2])) +# +--format=dlang +_D8demangle4testFNhG4fZv +demangle.test(__vector(float[4])) +# +--format=dlang +_D8demangle4testFNhG8fZv +demangle.test(__vector(float[8])) +# +--format=dlang +_D8demangle4testFNhG1dZv +demangle.test(__vector(double[1])) +# +--format=dlang +_D8demangle4testFNhG2dZv +demangle.test(__vector(double[2])) +# +--format=dlang +_D8demangle4testFNhG4dZv +demangle.test(__vector(double[4])) +# +--format=dlang +_D8demangle4testFI5identZv +demangle.test(ident) +# +--format=dlang +_D8demangle4testFI5ident4testZv +demangle.test(ident.test) +# +--format=dlang +_D8demangle4testFC5classZv +demangle.test(class) +# +--format=dlang +_D8demangle4testFC5class4testZv +demangle.test(class.test) +# +--format=dlang +_D8demangle4testFS6structZv +demangle.test(struct) +# +--format=dlang +_D8demangle4testFS6struct4testZv +demangle.test(struct.test) +# +--format=dlang +_D8demangle4testFE4enumZv +demangle.test(enum) +# +--format=dlang +_D8demangle4testFE4enum4testZv +demangle.test(enum.test) +# +--format=dlang +_D8demangle4testFT7typedefZv +demangle.test(typedef) +# +--format=dlang +_D8demangle4testFT7typedef4testZv +demangle.test(typedef.test) +# +--format=dlang +_D8demangle4testFJaZv +demangle.test(out char) +# +--format=dlang +_D8demangle4testFKaZv +demangle.test(ref char) +# +--format=dlang +_D8demangle4testFLaZv +demangle.test(lazy char) +# +--format=dlang +_D8demangle4testFMaZv +demangle.test(scope char) +# +--format=dlang +_D8demangle4testFaXv +demangle.test(char...) +# +--format=dlang +_D8demangle4testFaYv +demangle.test(char, ...) +# +--format=dlang +_D8demangle4testFaaYv +demangle.test(char, char, ...) +# +--format=dlang +_D8demangle4testFaaZv +demangle.test(char, char) +# +--format=dlang +_D8demangle4testFB0Zv +demangle.test(Tuple!()) +# +--format=dlang +_D8demangle4testFB1aZv +demangle.test(Tuple!(char)) +# +--format=dlang +_D8demangle4testFB2aaZv +demangle.test(Tuple!(char, char)) +# +--format=dlang +_D8demangle4testFB3aaaZv +demangle.test(Tuple!(char, char, char)) +# +--format=dlang +_D8demangle4testFB2OaaZv +demangle.test(Tuple!(shared(char), char)) +# +--format=dlang +_D8demangle4testFB3aDFZaaZv +demangle.test(Tuple!(char, char() delegate, char)) +# +--format=dlang +_D8demangle4testFDFZaZv +demangle.test(char() delegate) +# +--format=dlang +_D8demangle4testFDUZaZv +demangle.test(extern(C) char() delegate) +# +--format=dlang +_D8demangle4testFDWZaZv +demangle.test(extern(Windows) char() delegate) +# +--format=dlang +_D8demangle4testFDVZaZv +demangle.test(extern(Pascal) char() delegate) +# +--format=dlang +_D8demangle4testFDRZaZv +demangle.test(extern(C++) char() delegate) +# +--format=dlang +_D8demangle4testFFZaZv +demangle.test(char() function) +# +--format=dlang +_D8demangle4testFUZaZv +demangle.test(extern(C) char() function) +# +--format=dlang +_D8demangle4testFWZaZv +demangle.test(extern(Windows) char() function) +# +--format=dlang +_D8demangle4testFVZaZv +demangle.test(extern(Pascal) char() function) +# +--format=dlang +_D8demangle4testFRZaZv +demangle.test(extern(C++) char() function) +# +--format=dlang +_D8demangle4testFDFNaZaZv +demangle.test(char() pure delegate) +# +--format=dlang +_D8demangle4testFDFNbZaZv +demangle.test(char() nothrow delegate) +# +--format=dlang +_D8demangle4testFDFNcZaZv +demangle.test(char() ref delegate) +# +--format=dlang +_D8demangle4testFDFNdZaZv +demangle.test(char() @property delegate) +# +--format=dlang +_D8demangle4testFDFNeZaZv +demangle.test(char() @trusted delegate) +# +--format=dlang +_D8demangle4testFDFNfZaZv +demangle.test(char() @safe delegate) +# +--format=dlang +_D8demangle4testFDFNiZaZv +demangle.test(char() @nogc delegate) +# +--format=dlang +_D8demangle4testFDFNaNbZaZv +demangle.test(char() pure nothrow delegate) +# +--format=dlang +_D8demangle4testFDFNbNaZaZv +demangle.test(char() nothrow pure delegate) +# +--format=dlang +_D8demangle4testFDFNdNfNaZaZv +demangle.test(char() @property @safe pure delegate) +# +--format=dlang +_D8demangle4testFFNaZaZv +demangle.test(char() pure function) +# +--format=dlang +_D8demangle4testFFNbZaZv +demangle.test(char() nothrow function) +# +--format=dlang +_D8demangle4testFFNcZaZv +demangle.test(char() ref function) +# +--format=dlang +_D8demangle4testFFNdZaZv +demangle.test(char() @property function) +# +--format=dlang +_D8demangle4testFFNeZaZv +demangle.test(char() @trusted function) +# +--format=dlang +_D8demangle4testFFNfZaZv +demangle.test(char() @safe function) +# +--format=dlang +_D8demangle4testFFNiZaZv +demangle.test(char() @nogc function) +# +--format=dlang +_D8demangle4testFFNaNbZaZv +demangle.test(char() pure nothrow function) +# +--format=dlang +_D8demangle4testFFNbNaZaZv +demangle.test(char() nothrow pure function) +# +--format=dlang +_D8demangle4testFFNdNfNaZaZv +demangle.test(char() @property @safe pure function) +# +--format=dlang +_D8demangle4test6__initZ +demangle.test.init$ +# +--format=dlang +_D8demangle4test6__vtblZ +vtable for demangle.test +# +--format=dlang +_D8demangle4test7__ClassZ +ClassInfo for demangle.test +# +--format=dlang +_D8demangle4test11__InterfaceZ +Interface for demangle.test +# +--format=dlang +_D8demangle4test12__ModuleInfoZ +ModuleInfo for demangle.test +# +--format=dlang +_D8demangle4test6__ctorMFZv +demangle.test.this() +# +--format=dlang +_D8demangle4test6__dtorMFZv +demangle.test.~this() +# +--format=dlang +_D8demangle4test6__postblitMFZv +demangle.test.this(this) +# +--format=dlang +_D8demangle4testFHAbaZv +demangle.test(char[bool[]]) +# +--format=dlang +_D8demangle4testFHG42caZv +demangle.test(char[creal[42]]) +# +--format=dlang +_D8demangle4testFAiXv +demangle.test(int[]...) +# +--format=dlang +_D8demangle4testFLAiXv +demangle.test(lazy int[]...) +# +--format=dlang +_D8demangle4testFAiYv +demangle.test(int[], ...) +# +--format=dlang +_D8demangle4testFLAiYv +demangle.test(lazy int[], ...) +# +--format=dlang +_D8demangle4testFLilZv +demangle.test(lazy int, long) +# +--format=dlang +_D8demangle4testFLliZv +demangle.test(lazy long, int) +# +--format=dlang +_D8demangle4testFLC6ObjectLDFLiZiZi +demangle.test(lazy Object, lazy int(lazy int) delegate) +# +--format=dlang +_D8demangle9__T4testZv +demangle.test!() +# +--format=dlang +_D8demangle11__T4testTaZv +demangle.test!(char) +# +--format=dlang +_D8demangle13__T4testTaTaZv +demangle.test!(char, char) +# +--format=dlang +_D8demangle15__T4testTaTaTaZv +demangle.test!(char, char, char) +# +--format=dlang +_D8demangle16__T4testTaTOiTaZv +demangle.test!(char, shared(int), char) +# +--format=dlang +_D8demangle17__T4testS6symbolZv +demangle.test!(symbol) +# +--format=dlang +_D8demangle21__T4testS6symbol3fooZv +demangle.test!(symbol.foo) +# +--format=dlang +_D8demangle25__T4testS6symbol3foo3barZv +demangle.test!(symbol.foo.bar) +# +--format=dlang +_D8demangle19__T4testTaS6symbolZv +demangle.test!(char, symbol) +# +--format=dlang +_D8demangle19__T4testS6symbolTaZv +demangle.test!(symbol, char) +# +--format=dlang +_D8demangle13__T4testVPinZv +demangle.test!(null) +# +--format=dlang +_D8demangle14__T4testVg123Zv +demangle.test!(123) +# +--format=dlang +_D8demangle14__T4testVi123Zv +demangle.test!(123) +# +--format=dlang +_D8demangle14__T4testVs123Zv +demangle.test!(123) +# +--format=dlang +_D8demangle14__T4testVh123Zv +demangle.test!(123u) +# +--format=dlang +_D8demangle14__T4testVk123Zv +demangle.test!(123u) +# +--format=dlang +_D8demangle14__T4testVt123Zv +demangle.test!(123u) +# +--format=dlang +_D8demangle14__T4testVl123Zv +demangle.test!(123L) +# +--format=dlang +_D8demangle14__T4testVm123Zv +demangle.test!(123uL) +# +--format=dlang +_D8demangle15__T4testViN123Zv +demangle.test!(-123) +# +--format=dlang +_D8demangle15__T4testVkN123Zv +demangle.test!(-123u) +# +--format=dlang +_D8demangle15__T4testVlN123Zv +demangle.test!(-123L) +# +--format=dlang +_D8demangle15__T4testVmN123Zv +demangle.test!(-123uL) +# +--format=dlang +_D8demangle12__T4testVb1Zv +demangle.test!(true) +# +--format=dlang +_D8demangle12__T4testVb0Zv +demangle.test!(false) +# +--format=dlang +_D8demangle13__T4testVa10Zv +demangle.test!('\x0a') +# +--format=dlang +_D8demangle13__T4testVa32Zv +demangle.test!(' ') +# +--format=dlang +_D8demangle13__T4testVa65Zv +demangle.test!('A') +# +--format=dlang +_D8demangle14__T4testVa126Zv +demangle.test!('~') +# +--format=dlang +_D8demangle15__T4testVu1000Zv +demangle.test!('\u03e8') +# +--format=dlang +_D8demangle17__T4testVw100000Zv +demangle.test!('\U000186a0') +# +--format=dlang +_D8demangle17__T4testVde0A8P6Zv +demangle.test!(42.0000) +# +--format=dlang +_D8demangle16__T4testVdeA8P2Zv +demangle.test!(42.0000) +# +--format=dlang +_D8demangle18__T4testVdeN0A8P6Zv +demangle.test!(-42.0000) +# +--format=dlang +_D8demangle31__T4testVde0F6E978D4FDF3B646P7Zv +demangle.test!(123.456) +# +--format=dlang +_D8demangle15__T4testVdeNANZv +demangle.test!(NaN) +# +--format=dlang +_D8demangle15__T4testVdeINFZv +demangle.test!(Inf) +# +--format=dlang +_D8demangle16__T4testVdeNINFZv +demangle.test!(-Inf) +# +--format=dlang +_D8demangle23__T4testVfe0FFFFFFP128Zv +demangle.test!(3.40282e+38) +# +--format=dlang +_D8demangle32__T4testVde0FFFFFFFFFFFFF8P1024Zv +demangle.test!(1.79769e+308) +# +--format=dlang +_D8demangle19__T4testVfe08PN125Zv +demangle.test!(1.17549e-38) +# +--format=dlang +_D8demangle20__T4testVde08PN1021Zv +demangle.test!(2.22507e-308) +# +--format=dlang +_D8demangle51__T4testVrc0C4CCCCCCCCCCCCCDP4c0B666666666666666P6Zv +demangle.test!(12.3000+45.6000i) +# +--format=dlang +_D8demangle52__T4testVrcN0C4CCCCCCCCCCCCCDP4c0B666666666666666P6Zv +demangle.test!(-12.3000+45.6000i) +# +--format=dlang +_D8demangle22__T4testVG3ua3_616263Zv +demangle.test!("abc") +# +--format=dlang +_D8demangle22__T4testVG3ud3_616263Zv +demangle.test!("abc"d) +# +--format=dlang +_D8demangle22__T4testVG3uw3_616263Zv +demangle.test!("abc"w) +# +--format=dlang +_D8demangle22__T4testVAiA4i1i2i3i4Zv +demangle.test!([1, 2, 3, 4]) +# +--format=dlang +_D8demangle25__T4testVAdA2e08P1eN08P1Zv +demangle.test!([1.00000, -1.00000]) +# +--format=dlang +_D8demangle23__T4testVHiiA2i1i2i3i4Zv +demangle.test!([1:2, 3:4]) +# +--format=dlang +_D8demangle39__T4testVHAxaiA2a3_616263i1a3_646566i2Zv +demangle.test!(["abc":1, "def":2]) +# +--format=dlang +_D8demangle28__T4testVS8demangle1SS2i1i2Zv +demangle.test!(demangle.S(1, 2)) +# +--format=dlang +_D8demangle35__T4testVS8demangle1SS2i1a3_616263Zv +demangle.test!(demangle.S(1, "abc")) +# +# Unittests +# +--format=dlang +printf +printf +# +--format=dlang +_foo +_foo +# +--format=dlang +_D88 +_D88 +# +--format=dlang +_D5__T1aZv +_D5__T1aZv +# +--format=dlang +_D4test3fooAa +test.foo +# +--format=dlang +_D8demangle8demangleFAaZAa +demangle.demangle(char[]) +# +--format=dlang +_D6object6Object8opEqualsFC6ObjectZi +object.Object.opEquals(Object) +# +--format=dlang +_D6object6Object8opAssignFC6ObjectZi +object.Object.opAssign(Object) +# +--format=dlang +_D4test2dgDFiYd +test.dg +# +--format=dlang +_D1a1bi +a.b +# +--format=dlang +_D1a1bPFiZi +a.b +# +--format=dlang +_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi +test.bar!("abc"w, "def"d).x +# +--format=dlang +_D6plugin8generateFiiZAya +plugin.generate(int, int) +# +--format=dlang +_D6plugin8generateFiiZAxa +plugin.generate(int, int) +# +--format=dlang +_D6plugin8generateFiiZAOa +plugin.generate(int, int) +# +--format=dlang +_D8demangle3fnAFZv3fnBMFZv +demangle.fnA().fnB() +# +--format=dlang +_D8demangle4mainFZv1S3fnCFZv +demangle.main().S.fnC() +# +--format=dlang +_D8demangle4mainFZv1S3fnDMFZv +demangle.main().S.fnD() +# +--format=dlang +_D8demangle4mainFZv5localMFZi +demangle.main().local() +# +--format=dlang +_D3std5ascii9uppercaseyAa +std.ascii.uppercase +# +--format=dlang +_D3std6stream9BOMEndianyG5E3std6system6Endian +std.stream.BOMEndian +# +--format=dlang +_D3std8internal7uni_tab10unicodeNkoyS3std8internal3uni12CodepointSet +std.internal.uni_tab.unicodeNko +# +--format=dlang +_D2gc2gc2GC6addrOfMFPvZPv +gc.gc.GC.addrOf(void*) +# +--format=dlang +_D3std7process10setCLOEXECFibZv +std.process.setCLOEXEC(int, bool) +# +--format=dlang +_D3std6digest2md3MD53putMFNaNbNeMAxhXv +std.digest.md.MD5.put(scope const(ubyte)[]...) +# +--format=dlang +_D3std6mmfile6MmFile13opIndexAssignMFhmZh +std.mmfile.MmFile.opIndexAssign(ubyte, ulong) +# +--format=dlang +_D3std7process18escapeShellCommandFxAAaXAya +std.process.escapeShellCommand(const(char[][])...) +# +--format=dlang +_D4core4sync5mutex5Mutex6__ctorMFC6ObjectZC4core4sync5mutex5Mutex +core.sync.mutex.Mutex.this(Object) +# +--format=dlang +_D6object14TypeInfo_Array8argTypesMFNbNfJC8TypeInfoJC8TypeInfoZi +object.TypeInfo_Array.argTypes(out TypeInfo, out TypeInfo) +# +--format=dlang +_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7tryExecMFMDFZvZv +rt.dmain2._d_run_main(int, char**, extern(C) int(char[][]) function*).tryExec(scope void() delegate) +# +--format=dlang +_D6object9Exception6__ctorMFNaNbNfAyaAyamC6object9ThrowableZC9Exception +object.Exception.this(immutable(char)[], immutable(char)[], ulong, object.Throwable) +# +--format=dlang +_D3gcc3deh17parse_lsda_headerFPS3gcc6unwind7generic15_Unwind_ContextPhPS3gcc3deh16lsda_header_infoZPh +gcc.deh.parse_lsda_header(gcc.unwind.generic._Unwind_Context*, ubyte*, gcc.deh.lsda_header_info*) +# +--format=dlang +_D3std6socket23UnknownAddressReference6__ctorMFPS4core3sys5posix3sys6socket8sockaddrkZC3std6socket23UnknownAddressReference +std.socket.UnknownAddressReference.this(core.sys.posix.sys.socket.sockaddr*, uint) +# +--format=dlang +_D8demangle20__T2fnVAiA4i1i2i3i4Z2fnFZv +demangle.fn!([1, 2, 3, 4]).fn() +# +--format=dlang +_D8demangle10__T2fnVi1Z2fnFZv +demangle.fn!(1).fn() +# +--format=dlang +_D8demangle26__T2fnVS8demangle1SS2i1i2Z2fnFZv +demangle.fn!(demangle.S(1, 2)).fn() +# +--format=dlang +_D8demangle13__T2fnVeeNANZ2fnFZv +demangle.fn!(NaN).fn() +# +--format=dlang +_D8demangle14__T2fnVeeNINFZ2fnFZv +demangle.fn!(-Inf).fn() +# +--format=dlang +_D8demangle13__T2fnVeeINFZ2fnFZv +demangle.fn!(Inf).fn() +# +--format=dlang +_D8demangle21__T2fnVHiiA2i1i2i3i4Z2fnFZv +demangle.fn!([1:2, 3:4]).fn() +# +--format=dlang +_D8demangle2fnFNgiZNgi +demangle.fn(inout(int)) +# +--format=dlang +_D8demangle29__T2fnVa97Va9Va0Vu257Vw65537Z2fnFZv +demangle.fn!('a', '\x09', '\x00', '\u0101', '\U00010001').fn() +# +--format=dlang +_D2gc11gctemplates56__T8mkBitmapTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ8mkBitmapFNbNiNfPmmZv +gc.gctemplates.mkBitmap!(std.range.iota!(int, int).iota(int, int).Result).mkBitmap(ulong*, ulong) +# +--format=dlang +_D8serenity9persister6Sqlite70__T15SqlitePersisterTS8serenity9persister6Sqlite11__unittest6FZv4TestZ15SqlitePersister12__T7opIndexZ7opIndexMFmZS8serenity9persister6Sqlite11__unittest6FZv4Test +serenity.persister.Sqlite.SqlitePersister!(serenity.persister.Sqlite.__unittest6().Test).SqlitePersister.opIndex!().opIndex(ulong) +# +--format=dlang +_D4test4mainFZv5localMFZi +test.main().local()