• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修訂b55f967878a4f7905f78b05a9c37457797b1c7ed (tree)
時間2014-10-11 18:29:10
作者Iain Buclaw <ibuclaw@gdcp...>
CommiterIain Buclaw

Log Message

Sync libiberty with upstream GCC.

include/ChangeLog
* libiberty.h (PEX_STDOUT_APPEND): New flag.
(PEX_STDERR_APPEND): Likewise.

* 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.

* longlong.h: Add udiv_w_sdiv prototype.

libiberty/ChangeLog
* cp-demangle.c (d_substitution): Handle abi tags on abbreviation.

* pex-common.h (struct pex_funcs): Add new parameter for open_write field.
* pex-unix.c (pex_unix_open_write): Add support for new parameter.
* pex-djgpp.c (pex_djgpp_open_write): Likewise.
* pex-win32.c (pex_win32_open_write): Likewise.
* pex-common.c (pex_run_in_environment): Likewise.

* 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.

* simple-object-elf.c (simple_object_elf_write_ehdr): Correctly
handle objects with more than SHN_LORESERVE sections.
(simple_object_elf_write_shdr): Add sh_link parameter.
(simple_object_elf_write_to_file): Correctly handle objects with
more than SHN_LORESERVE sections.

* cp-demangle.c (d_dump): Only access field from s_fixed part of
the union for DEMANGLE_COMPONENT_FIXED_TYPE.
(d_count_templates_scopes): Likewise.

* testsuite/demangler-fuzzer.c: New file.
* testsuite/Makefile.in (fuzz-demangler): New rule.
(demangler-fuzzer): Likewise.
(mostlyclean): Clean up demangler fuzzer.

Change Summary

差異

--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,21 @@
1+2014-09-26 Max Ostapenko <m.ostapenko@partner.samsung.com>
2+
3+ * libiberty.h (PEX_STDOUT_APPEND): New flag.
4+ (PEX_STDERR_APPEND): Likewise.
5+
6+2014-09-23 Iain Buclaw <ibuclaw@gdcproject.org>
7+
8+ * demangle.h (DMGL_DLANG): New macro.
9+ (DMGL_STYLE_MASK): Add DMGL_DLANG.
10+ (demangling_styles): Add dlang_demangling.
11+ (DLANG_DEMANGLING_STYLE_STRING): New macro.
12+ (DLANG_DEMANGLING): New macro.
13+ (dlang_demangle): New prototype.
14+
15+2014-09-15 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
16+
17+ * longlong.h: Add __udiv_w_sdiv prototype.
18+
119 2014-08-12 Alan Modra <amodra@gmail.com>
220
321 * bfdlink.h (struct bfd_link_callbacks <notice>): Remove "string"
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -63,9 +63,10 @@ extern "C" {
6363 #define DMGL_EDG (1 << 13)
6464 #define DMGL_GNU_V3 (1 << 14)
6565 #define DMGL_GNAT (1 << 15)
66+#define DMGL_DLANG (1 << 16)
6667
6768 /* If none of these are set, use 'current_demangling_style' as the default. */
68-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT)
69+#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)
6970
7071 /* Enumeration of possible demangling styles.
7172
@@ -87,7 +88,8 @@ extern enum demangling_styles
8788 edg_demangling = DMGL_EDG,
8889 gnu_v3_demangling = DMGL_GNU_V3,
8990 java_demangling = DMGL_JAVA,
90- gnat_demangling = DMGL_GNAT
91+ gnat_demangling = DMGL_GNAT,
92+ dlang_demangling = DMGL_DLANG
9193 } current_demangling_style;
9294
9395 /* Define string names for the various demangling styles. */
@@ -102,6 +104,7 @@ extern enum demangling_styles
102104 #define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3"
103105 #define JAVA_DEMANGLING_STYLE_STRING "java"
104106 #define GNAT_DEMANGLING_STYLE_STRING "gnat"
107+#define DLANG_DEMANGLING_STYLE_STRING "dlang"
105108
106109 /* Some macros to test what demangling style is active. */
107110
@@ -115,6 +118,7 @@ extern enum demangling_styles
115118 #define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3)
116119 #define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
117120 #define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
121+#define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG)
118122
119123 /* Provide information about the available demangle styles. This code is
120124 pulled from gdb into libiberty because it is useful to binutils also. */
@@ -169,6 +173,9 @@ java_demangle_v3 (const char *mangled);
169173 char *
170174 ada_demangle (const char *mangled, int options);
171175
176+extern char *
177+dlang_demangle (const char *mangled, int options);
178+
172179 enum gnu_v3_ctor_kinds {
173180 gnu_v3_complete_object_ctor = 1,
174181 gnu_v3_base_object_ctor,
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -106,7 +106,10 @@ extern int countargv (char**);
106106 to find the declaration so provide a fully prototyped one. If it
107107 is 1, we found it so don't provide any declaration at all. */
108108 #if !HAVE_DECL_BASENAME
109-#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) || defined (HAVE_DECL_BASENAME)
109+#if defined (__GNU_LIBRARY__ ) || defined (__linux__) \
110+ || defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__) \
111+ || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) \
112+ || defined (__DragonFly__) || defined (HAVE_DECL_BASENAME)
110113 extern char *basename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1);
111114 #else
112115 /* Do not allow basename to be used if there is no prototype seen. We
@@ -442,6 +445,11 @@ extern struct pex_obj *pex_init (int flags, const char *pname,
442445 on Unix. */
443446 #define PEX_BINARY_ERROR 0x80
444447
448+/* Append stdout to existing file instead of truncating it. */
449+#define PEX_STDOUT_APPEND 0x100
450+
451+/* Thes same as PEX_STDOUT_APPEND, but for STDERR. */
452+#define PEX_STDERR_APPEND 0x200
445453
446454 /* Execute one program. Returns NULL on success. On error returns an
447455 error string (typically just the name of a system call); the error
@@ -633,6 +641,10 @@ extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3;
633641 extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0);
634642 #endif
635643
644+#if defined (HAVE_DECL_STRNLEN) && !HAVE_DECL_STRNLEN
645+extern size_t strnlen (const char *, size_t);
646+#endif
647+
636648 #if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
637649 /* Compare version strings. */
638650 extern int strverscmp (const char *, const char *);
--- a/include/longlong.h
+++ b/include/longlong.h
@@ -1687,7 +1687,8 @@ extern UHItype __stormy16_count_leading_zeros (UHItype);
16871687 #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
16881688 #define udiv_qrnnd(q, r, nh, nl, d) \
16891689 do { \
1690- USItype __r; \
1690+ extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype); \
1691+ UWtype __r; \
16911692 (q) = __udiv_w_sdiv (&__r, nh, nl, d); \
16921693 (r) = __r; \
16931694 } while (0)
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,46 @@
1+2014-09-26 Jason Merrill <jason@redhat.com>
2+
3+ * cp-demangle.c (d_substitution): Handle abi tags on abbreviation.
4+
5+2014-09-26 Max Ostapenko <m.ostapenko@partner.samsung.com>
6+
7+ * pex-common.h (struct pex_funcs): Add new parameter for open_write field.
8+ * pex-unix.c (pex_unix_open_write): Add support for new parameter.
9+ * pex-djgpp.c (pex_djgpp_open_write): Likewise.
10+ * pex-win32.c (pex_win32_open_write): Likewise.
11+ * pex-common.c (pex_run_in_environment): Likewise.
12+
13+2014-09-23 Iain Buclaw <ibuclaw@gdcproject.org>
14+
15+ * Makefile.in (CFILES): Add d-demangle.c.
16+ (REQUIRED_OFILES): Add d-demangle.o.
17+ * cplus-dem.c (libiberty_demanglers): Add dlang_demangling case.
18+ (cplus_demangle): Likewise.
19+ * d-demangle.c: New file.
20+ * testsuite/Makefile.in (really-check): Add check-d-demangle.
21+ * testsuite/d-demangle-expected: New file.
22+
23+2014-09-19 Ian Lance Taylor <iant@google.com>
24+
25+ * simple-object-elf.c (simple_object_elf_write_ehdr): Correctly
26+ handle objects with more than SHN_LORESERVE sections.
27+ (simple_object_elf_write_shdr): Add sh_link parameter.
28+ (simple_object_elf_write_to_file): Correctly handle objects with
29+ more than SHN_LORESERVE sections.
30+
31+2014-08-29 Andrew Burgess <aburgess@broadcom.com>
32+
33+ * cp-demangle.c (d_dump): Only access field from s_fixed part of
34+ the union for DEMANGLE_COMPONENT_FIXED_TYPE.
35+ (d_count_templates_scopes): Likewise.
36+
37+2014-08-13 Gary Benson <gbenson@redhat.com>
38+
39+ * testsuite/demangler-fuzzer.c: New file.
40+ * testsuite/Makefile.in (fuzz-demangler): New rule.
41+ (demangler-fuzzer): Likewise.
42+ (mostlyclean): Clean up demangler fuzzer.
43+
144 2014-06-11 Andrew Burgess <aburgess@broadcom.com>
245
346 * cplus-dem.c (do_type): Call string_delete even if the call to
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -127,7 +127,7 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \
127127 basename.c bcmp.c bcopy.c bsearch.c bzero.c \
128128 calloc.c choose-temp.c clock.c concat.c cp-demangle.c \
129129 cp-demint.c cplus-dem.c crc32.c \
130- dwarfnames.c dyn-string.c \
130+ d-demangle.c dwarfnames.c dyn-string.c \
131131 fdmatch.c ffs.c fibheap.c filename_cmp.c floatformat.c \
132132 fnmatch.c fopen_unlocked.c \
133133 getcwd.c getopt.c getopt1.c getpagesize.c getpwd.c getruntime.c \
@@ -167,7 +167,7 @@ REQUIRED_OFILES = \
167167 ./md5.$(objext) ./sha1.$(objext) ./alloca.$(objext) \
168168 ./argv.$(objext) \
169169 ./choose-temp.$(objext) ./concat.$(objext) \
170- ./cp-demint.$(objext) ./crc32.$(objext) \
170+ ./cp-demint.$(objext) ./crc32.$(objext) ./d-demangle.$(objext) \
171171 ./dwarfnames.$(objext) ./dyn-string.$(objext) \
172172 ./fdmatch.$(objext) ./fibheap.$(objext) \
173173 ./filename_cmp.$(objext) ./floatformat.$(objext) \
@@ -714,6 +714,14 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
714714 else true; fi
715715 $(COMPILE.c) $(srcdir)/dyn-string.c $(OUTPUT_OPTION)
716716
717+./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
718+ $(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \
719+ $(INCDIR)/dyn-string.h $(INCDIR)/getopt.h $(INCDIR)/libiberty.h
720+ if [ x"$(PICFLAG)" != x ]; then \
721+ $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
722+ else true; fi
723+ $(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
724+
717725 ./fdmatch.$(objext): $(srcdir)/fdmatch.c config.h $(INCDIR)/ansidecl.h \
718726 $(INCDIR)/libiberty.h
719727 if [ x"$(PICFLAG)" != x ]; then \
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -713,7 +713,9 @@ d_dump (struct demangle_component *dc, int indent)
713713 printf ("pointer to member type\n");
714714 break;
715715 case DEMANGLE_COMPONENT_FIXED_TYPE:
716- printf ("fixed-point type\n");
716+ printf ("fixed-point type, accum? %d, sat? %d\n",
717+ dc->u.s_fixed.accum, dc->u.s_fixed.sat);
718+ d_dump (dc->u.s_fixed.length, indent + 2)
717719 break;
718720 case DEMANGLE_COMPONENT_ARGLIST:
719721 printf ("argument list\n");
@@ -3685,6 +3687,7 @@ d_substitution (struct d_info *di, int prefix)
36853687 {
36863688 const char *s;
36873689 int len;
3690+ struct demangle_component *c;
36883691
36893692 if (p->set_last_name != NULL)
36903693 di->last_name = d_make_sub (di, p->set_last_name,
@@ -3700,7 +3703,15 @@ d_substitution (struct d_info *di, int prefix)
37003703 len = p->simple_len;
37013704 }
37023705 di->expansion += len;
3703- return d_make_sub (di, s, len);
3706+ c = d_make_sub (di, s, len);
3707+ if (d_peek_char (di) == 'B')
3708+ {
3709+ /* If there are ABI tags on the abbreviation, it becomes
3710+ a substitution candidate. */
3711+ c = d_abi_tags (di, c);
3712+ d_add_substitution (di, c);
3713+ }
3714+ return c;
37043715 }
37053716 }
37063717
@@ -3875,7 +3886,6 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
38753886 case DEMANGLE_COMPONENT_FUNCTION_TYPE:
38763887 case DEMANGLE_COMPONENT_ARRAY_TYPE:
38773888 case DEMANGLE_COMPONENT_PTRMEM_TYPE:
3878- case DEMANGLE_COMPONENT_FIXED_TYPE:
38793889 case DEMANGLE_COMPONENT_VECTOR_TYPE:
38803890 case DEMANGLE_COMPONENT_ARGLIST:
38813891 case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
@@ -3920,6 +3930,11 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
39203930 dc->u.s_extended_operator.name);
39213931 break;
39223932
3933+ case DEMANGLE_COMPONENT_FIXED_TYPE:
3934+ d_count_templates_scopes (num_templates, num_scopes,
3935+ dc->u.s_fixed.length);
3936+ break;
3937+
39233938 case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
39243939 case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
39253940 d_count_templates_scopes (num_templates, num_scopes,
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -306,6 +306,12 @@ const struct demangler_engine libiberty_demanglers[] =
306306 }
307307 ,
308308 {
309+ DLANG_DEMANGLING_STYLE_STRING,
310+ dlang_demangling,
311+ "DLANG style demangling"
312+ }
313+ ,
314+ {
309315 NULL, unknown_demangling, NULL
310316 }
311317 };
@@ -870,6 +876,13 @@ cplus_demangle (const char *mangled, int options)
870876 if (GNAT_DEMANGLING)
871877 return ada_demangle (mangled, options);
872878
879+ if (DLANG_DEMANGLING)
880+ {
881+ ret = dlang_demangle (mangled, options);
882+ if (ret)
883+ return ret;
884+ }
885+
873886 ret = internal_cplus_demangle (work, mangled);
874887 squangle_mop_up (work);
875888 return (ret);
--- /dev/null
+++ b/libiberty/d-demangle.c
@@ -0,0 +1,1338 @@
1+/* Demangler for the D programming language
2+ Copyright 2014 Free Software Foundation, Inc.
3+ Written by Iain Buclaw (ibuclaw@gdcproject.org)
4+
5+This file is part of the libiberty library.
6+Libiberty is free software; you can redistribute it and/or
7+modify it under the terms of the GNU Library General Public
8+License as published by the Free Software Foundation; either
9+version 2 of the License, or (at your option) any later version.
10+
11+In addition to the permissions in the GNU Library General Public
12+License, the Free Software Foundation gives you unlimited permission
13+to link the compiled version of this file into combinations with other
14+programs, and to distribute those combinations without any restriction
15+coming from the use of this file. (The Library Public License
16+restrictions do apply in other respects; for example, they cover
17+modification of the file, and distribution when not linked into a
18+combined executable.)
19+
20+Libiberty is distributed in the hope that it will be useful,
21+but WITHOUT ANY WARRANTY; without even the implied warranty of
22+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23+Library General Public License for more details.
24+
25+You should have received a copy of the GNU Library General Public
26+License along with libiberty; see the file COPYING.LIB.
27+If not, see <http://www.gnu.org/licenses/>. */
28+
29+/* This file exports one function; dlang_demangle.
30+
31+ This file imports strtol and strtold for decoding mangled literals. */
32+
33+#ifdef HAVE_CONFIG_H
34+#include "config.h"
35+#endif
36+
37+#include "safe-ctype.h"
38+
39+#include <sys/types.h>
40+#include <string.h>
41+#include <stdio.h>
42+
43+#ifdef HAVE_STDLIB_H
44+#include <stdlib.h>
45+#else
46+extern long strtol (const char *nptr, char **endptr, int base);
47+extern long double strtold (const char *nptr, char **endptr);
48+#endif
49+
50+#include <demangle.h>
51+#include "libiberty.h"
52+
53+/* A mini string-handling package */
54+
55+typedef struct string /* Beware: these aren't required to be */
56+{ /* '\0' terminated. */
57+ char *b; /* pointer to start of string */
58+ char *p; /* pointer after last character */
59+ char *e; /* pointer after end of allocated space */
60+} string;
61+
62+static void
63+string_need (string *s, int n)
64+{
65+ int tem;
66+
67+ if (s->b == NULL)
68+ {
69+ if (n < 32)
70+ {
71+ n = 32;
72+ }
73+ s->p = s->b = XNEWVEC (char, n);
74+ s->e = s->b + n;
75+ }
76+ else if (s->e - s->p < n)
77+ {
78+ tem = s->p - s->b;
79+ n += tem;
80+ n *= 2;
81+ s->b = XRESIZEVEC (char, s->b, n);
82+ s->p = s->b + tem;
83+ s->e = s->b + n;
84+ }
85+}
86+
87+static void
88+string_delete (string *s)
89+{
90+ if (s->b != NULL)
91+ {
92+ XDELETEVEC (s->b);
93+ s->b = s->e = s->p = NULL;
94+ }
95+}
96+
97+static void
98+string_init (string *s)
99+{
100+ s->b = s->p = s->e = NULL;
101+}
102+
103+static int
104+string_length (string *s)
105+{
106+ if (s->p == s->b)
107+ {
108+ return 0;
109+ }
110+ return s->p - s->b;
111+}
112+
113+static void
114+string_setlength (string *s, int n)
115+{
116+ if (n - string_length (s) < 0)
117+ {
118+ s->p = s->b + n;
119+ }
120+}
121+
122+static void
123+string_append (string *p, const char *s)
124+{
125+ int n = strlen (s);
126+ string_need (p, n);
127+ memcpy (p->p, s, n);
128+ p->p += n;
129+}
130+
131+static void
132+string_appendn (string *p, const char *s, int n)
133+{
134+ if (n != 0)
135+ {
136+ string_need (p, n);
137+ memcpy (p->p, s, n);
138+ p->p += n;
139+ }
140+}
141+
142+static void
143+string_prependn (string *p, const char *s, int n)
144+{
145+ char *q;
146+
147+ if (n != 0)
148+ {
149+ string_need (p, n);
150+ for (q = p->p - 1; q >= p->b; q--)
151+ {
152+ q[n] = q[0];
153+ }
154+ memcpy (p->b, s, n);
155+ p->p += n;
156+ }
157+}
158+
159+static void
160+string_prepend (string *p, const char *s)
161+{
162+ if (s != NULL && *s != '\0')
163+ {
164+ string_prependn (p, s, strlen (s));
165+ }
166+}
167+
168+/* Prototypes for forward referenced functions */
169+static const char *dlang_function_args (string *, const char *);
170+
171+static const char *dlang_type (string *, const char *);
172+
173+static const char *dlang_value (string *, const char *, const char *, char);
174+
175+static const char *dlang_parse_symbol (string *, const char *);
176+
177+static const char *dlang_parse_tuple (string *, const char *);
178+
179+static const char *dlang_parse_template (string *, const char *, long);
180+
181+
182+/* Demangle the calling convention from MANGLED and append it to DECL.
183+ Return the remaining string on success or NULL on failure. */
184+static const char *
185+dlang_call_convention (string *decl, const char *mangled)
186+{
187+ if (mangled == NULL || *mangled == '\0')
188+ return mangled;
189+
190+ switch (*mangled)
191+ {
192+ case 'F': /* (D) */
193+ mangled++;
194+ break;
195+ case 'U': /* (C) */
196+ mangled++;
197+ string_append (decl, "extern(C) ");
198+ break;
199+ case 'W': /* (Windows) */
200+ mangled++;
201+ string_append (decl, "extern(Windows) ");
202+ break;
203+ case 'V': /* (Pascal) */
204+ mangled++;
205+ string_append (decl, "extern(Pascal) ");
206+ break;
207+ case 'R': /* (C++) */
208+ mangled++;
209+ string_append (decl, "extern(C++) ");
210+ break;
211+ default:
212+ return NULL;
213+ }
214+
215+ return mangled;
216+}
217+
218+/* Demangle the D function attributes from MANGLED and append it to DECL.
219+ Return the remaining string on success or NULL on failure. */
220+static const char *
221+dlang_attributes (string *decl, const char *mangled)
222+{
223+ if (mangled == NULL || *mangled == '\0')
224+ return mangled;
225+
226+ while (*mangled == 'N')
227+ {
228+ mangled++;
229+ switch (*mangled)
230+ {
231+ case 'a': /* pure */
232+ mangled++;
233+ string_append (decl, "pure ");
234+ continue;
235+ case 'b': /* nothrow */
236+ mangled++;
237+ string_append (decl, "nothrow ");
238+ continue;
239+ case 'c': /* ref */
240+ mangled++;
241+ string_append (decl, "ref ");
242+ continue;
243+ case 'd': /* @property */
244+ mangled++;
245+ string_append (decl, "@property ");
246+ continue;
247+ case 'e': /* @trusted */
248+ mangled++;
249+ string_append (decl, "@trusted ");
250+ continue;
251+ case 'f': /* @safe */
252+ mangled++;
253+ string_append (decl, "@safe ");
254+ continue;
255+ case 'g':
256+ case 'h':
257+ /* inout parameter is represented as 'Ng'.
258+ vector parameter is represented as 'Nh'.
259+ If we see this, then we know we're really in the
260+ parameter list. Rewind and break. */
261+ mangled--;
262+ break;
263+ case 'i': /* @nogc */
264+ mangled++;
265+ string_append (decl, "@nogc ");
266+ continue;
267+ }
268+ break;
269+ }
270+
271+ return mangled;
272+}
273+
274+/* Demangle the function type from MANGLED and append it to DECL.
275+ Return the remaining string on success or NULL on failure. */
276+static const char *
277+dlang_function_type (string *decl, const char *mangled)
278+{
279+ string attr, args, type;
280+ size_t szattr, szargs, sztype;
281+
282+ if (mangled == NULL || *mangled == '\0')
283+ return mangled;
284+
285+ /* The order of the mangled string is:
286+ CallConvention FuncAttrs Arguments ArgClose Type
287+
288+ The demangled string is re-ordered as:
289+ CallConvention Type Arguments FuncAttrs
290+ */
291+ string_init (&attr);
292+ string_init (&args);
293+ string_init (&type);
294+
295+ /* Function call convention. */
296+ mangled = dlang_call_convention (decl, mangled);
297+
298+ /* Function attributes. */
299+ mangled = dlang_attributes (&attr, mangled);
300+ szattr = string_length (&attr);
301+
302+ /* Function arguments. */
303+ mangled = dlang_function_args (&args, mangled);
304+ szargs = string_length (&args);
305+
306+ /* Function return type. */
307+ mangled = dlang_type (&type, mangled);
308+ sztype = string_length (&type);
309+
310+ /* Append to decl in order. */
311+ string_appendn (decl, type.b, sztype);
312+ string_append (decl, "(");
313+ string_appendn (decl, args.b, szargs);
314+ string_append (decl, ") ");
315+ string_appendn (decl, attr.b, szattr);
316+
317+ string_delete (&attr);
318+ string_delete (&args);
319+ string_delete (&type);
320+ return mangled;
321+}
322+
323+/* Demangle the argument list from MANGLED and append it to DECL.
324+ Return the remaining string on success or NULL on failure. */
325+static const char *
326+dlang_function_args (string *decl, const char *mangled)
327+{
328+ size_t n = 0;
329+
330+ while (mangled && *mangled != '\0')
331+ {
332+ switch (*mangled)
333+ {
334+ case 'X': /* (variadic T t...) style. */
335+ mangled++;
336+ string_append (decl, "...");
337+ return mangled;
338+ case 'Y': /* (variadic T t, ...) style. */
339+ mangled++;
340+ string_append (decl, ", ...");
341+ return mangled;
342+ case 'Z': /* Normal function. */
343+ mangled++;
344+ return mangled;
345+ }
346+
347+ if (n++)
348+ string_append (decl, ", ");
349+
350+ if (*mangled == 'M') /* scope(T) */
351+ {
352+ mangled++;
353+ string_append (decl, "scope ");
354+ }
355+
356+ switch (*mangled)
357+ {
358+ case 'J': /* out(T) */
359+ mangled++;
360+ string_append (decl, "out ");
361+ break;
362+ case 'K': /* ref(T) */
363+ mangled++;
364+ string_append (decl, "ref ");
365+ break;
366+ case 'L': /* lazy(T) */
367+ mangled++;
368+ string_append (decl, "lazy ");
369+ break;
370+ }
371+ mangled = dlang_type (decl, mangled);
372+ }
373+
374+ return mangled;
375+}
376+
377+/* Demangle the type from MANGLED and append it to DECL.
378+ Return the remaining string on success or NULL on failure. */
379+static const char *
380+dlang_type (string *decl, const char *mangled)
381+{
382+ if (mangled == NULL || *mangled == '\0')
383+ return mangled;
384+
385+ switch (*mangled)
386+ {
387+ case 'O': /* shared(T) */
388+ mangled++;
389+ string_append (decl, "shared(");
390+ mangled = dlang_type (decl, mangled);
391+ string_append (decl, ")");
392+ return mangled;
393+ case 'x': /* const(T) */
394+ mangled++;
395+ string_append (decl, "const(");
396+ mangled = dlang_type (decl, mangled);
397+ string_append (decl, ")");
398+ return mangled;
399+ case 'y': /* immutable(T) */
400+ mangled++;
401+ string_append (decl, "immutable(");
402+ mangled = dlang_type (decl, mangled);
403+ string_append (decl, ")");
404+ return mangled;
405+ case 'N':
406+ mangled++;
407+ if (*mangled == 'g') /* wild(T) */
408+ {
409+ mangled++;
410+ string_append (decl, "inout(");
411+ mangled = dlang_type (decl, mangled);
412+ string_append (decl, ")");
413+ return mangled;
414+ }
415+ else if (*mangled == 'h') /* vector(T) */
416+ {
417+ mangled++;
418+ string_append (decl, "__vector(");
419+ mangled = dlang_type (decl, mangled);
420+ string_append (decl, ")");
421+ return mangled;
422+ }
423+ else
424+ return NULL;
425+ case 'A': /* dynamic array (T[]) */
426+ mangled++;
427+ mangled = dlang_type (decl, mangled);
428+ string_append (decl, "[]");
429+ return mangled;
430+ case 'G': /* static array (T[N]) */
431+ {
432+ const char *numptr;
433+ size_t num = 0;
434+ mangled++;
435+
436+ numptr = mangled;
437+ while (ISDIGIT (*mangled))
438+ {
439+ num++;
440+ mangled++;
441+ }
442+ mangled = dlang_type (decl, mangled);
443+ string_append (decl, "[");
444+ string_appendn (decl, numptr, num);
445+ string_append (decl, "]");
446+ return mangled;
447+ }
448+ case 'H': /* associative array (T[T]) */
449+ {
450+ string type;
451+ size_t sztype;
452+ mangled++;
453+
454+ string_init (&type);
455+ mangled = dlang_type (&type, mangled);
456+ sztype = string_length (&type);
457+
458+ mangled = dlang_type (decl, mangled);
459+ string_append (decl, "[");
460+ string_appendn (decl, type.b, sztype);
461+ string_append (decl, "]");
462+
463+ string_delete (&type);
464+ return mangled;
465+ }
466+ case 'P': /* pointer (T*) */
467+ mangled++;
468+ mangled = dlang_type (decl, mangled);
469+ string_append (decl, "*");
470+ return mangled;
471+ case 'I': /* ident T */
472+ case 'C': /* class T */
473+ case 'S': /* struct T */
474+ case 'E': /* enum T */
475+ case 'T': /* typedef T */
476+ mangled++;
477+ return dlang_parse_symbol (decl, mangled);
478+ case 'D': /* delegate T */
479+ mangled++;
480+ mangled = dlang_function_type (decl, mangled);
481+ string_append (decl, "delegate");
482+ return mangled;
483+ case 'B': /* tuple T */
484+ mangled++;
485+ return dlang_parse_tuple (decl, mangled);
486+
487+ /* Function types */
488+ case 'F': case 'U': case 'W':
489+ case 'V': case 'R':
490+ mangled = dlang_function_type (decl, mangled);
491+ string_append (decl, "function");
492+ return mangled;
493+
494+ /* Basic types */
495+ case 'n':
496+ mangled++;
497+ string_append (decl, "none");
498+ return mangled;
499+ case 'v':
500+ mangled++;
501+ string_append (decl, "void");
502+ return mangled;
503+ case 'g':
504+ mangled++;
505+ string_append (decl, "byte");
506+ return mangled;
507+ case 'h':
508+ mangled++;
509+ string_append (decl, "ubyte");
510+ return mangled;
511+ case 's':
512+ mangled++;
513+ string_append (decl, "short");
514+ return mangled;
515+ case 't':
516+ mangled++;
517+ string_append (decl, "ushort");
518+ return mangled;
519+ case 'i':
520+ mangled++;
521+ string_append (decl, "int");
522+ return mangled;
523+ case 'k':
524+ mangled++;
525+ string_append (decl, "uint");
526+ return mangled;
527+ case 'l':
528+ mangled++;
529+ string_append (decl, "long");
530+ return mangled;
531+ case 'm':
532+ mangled++;
533+ string_append (decl, "ulong");
534+ return mangled;
535+ case 'f':
536+ mangled++;
537+ string_append (decl, "float");
538+ return mangled;
539+ case 'd':
540+ mangled++;
541+ string_append (decl, "double");
542+ return mangled;
543+ case 'e':
544+ mangled++;
545+ string_append (decl, "real");
546+ return mangled;
547+
548+ /* Imaginary and Complex types */
549+ case 'o':
550+ mangled++;
551+ string_append (decl, "ifloat");
552+ return mangled;
553+ case 'p':
554+ mangled++;
555+ string_append (decl, "idouble");
556+ return mangled;
557+ case 'j':
558+ mangled++;
559+ string_append (decl, "ireal");
560+ return mangled;
561+ case 'q':
562+ mangled++;
563+ string_append (decl, "cfloat");
564+ return mangled;
565+ case 'r':
566+ mangled++;
567+ string_append (decl, "cdouble");
568+ return mangled;
569+ case 'c':
570+ mangled++;
571+ string_append (decl, "creal");
572+ return mangled;
573+
574+ /* Other types */
575+ case 'b':
576+ mangled++;
577+ string_append (decl, "bool");
578+ return mangled;
579+ case 'a':
580+ mangled++;
581+ string_append (decl, "char");
582+ return mangled;
583+ case 'u':
584+ mangled++;
585+ string_append (decl, "wchar");
586+ return mangled;
587+ case 'w':
588+ mangled++;
589+ string_append (decl, "dchar");
590+ return mangled;
591+
592+ default: /* unhandled */
593+ return NULL;
594+ }
595+}
596+
597+/* Extract the identifier from MANGLED and append it to DECL.
598+ Return the remaining string on success or NULL on failure. */
599+static const char *
600+dlang_identifier (string *decl, const char *mangled)
601+{
602+ if (mangled == NULL || *mangled == '\0')
603+ return mangled;
604+
605+ if (ISDIGIT (*mangled))
606+ {
607+ char *endptr;
608+ long i = strtol (mangled, &endptr, 10);
609+
610+ if (endptr == NULL || i <= 0 || strlen (endptr) < (size_t) i)
611+ return NULL;
612+
613+ mangled = endptr;
614+
615+ /* May be a template instance. */
616+ if (i >= 5 && strncmp (mangled, "__T", 3) == 0)
617+ {
618+ /* Template symbol. */
619+ if (ISDIGIT (mangled[3]) && mangled[3] != '0')
620+ return dlang_parse_template (decl, mangled, i);
621+
622+ return NULL;
623+ }
624+
625+ if (strncmp (mangled, "__ctor", i) == 0)
626+ {
627+ /* Constructor symbol for a class/struct. */
628+ string_append (decl, "this");
629+ mangled += i;
630+ return mangled;
631+ }
632+ else if (strncmp (mangled, "__dtor", i) == 0)
633+ {
634+ /* Destructor symbol for a class/struct. */
635+ string_append (decl, "~this");
636+ mangled += i;
637+ return mangled;
638+ }
639+ else if (strncmp (mangled, "__postblit", i) == 0)
640+ {
641+ /* Postblit symbol for a struct. */
642+ string_append (decl, "this(this)");
643+ mangled += i;
644+ return mangled;
645+ }
646+ else if (strncmp (mangled, "__initZ", i+1) == 0)
647+ {
648+ /* The static initialiser for a given symbol. */
649+ string_append (decl, "init$");
650+ mangled += i + 1;
651+ return mangled;
652+ }
653+ else if (strncmp (mangled, "__ClassZ", i+1) == 0)
654+ {
655+ /* The classinfo symbol for a given class. */
656+ string_prepend (decl, "ClassInfo for ");
657+ string_setlength (decl, string_length (decl) - 1);
658+ mangled += i + 1;
659+ return mangled;
660+ }
661+ else if (strncmp (mangled, "__vtblZ", i+1) == 0)
662+ {
663+ /* The vtable symbol for a given class. */
664+ string_prepend (decl, "vtable for ");
665+ string_setlength (decl, string_length (decl) - 1);
666+ mangled += i + 1;
667+ return mangled;
668+ }
669+ else if (strncmp (mangled, "__InterfaceZ", i+1) == 0)
670+ {
671+ /* The interface symbol for a given class. */
672+ string_prepend (decl, "Interface for ");
673+ string_setlength (decl, string_length (decl) - 1);
674+ mangled += i + 1;
675+ return mangled;
676+ }
677+ else if (strncmp (mangled, "__ModuleInfoZ", i+1) == 0)
678+ {
679+ /* The ModuleInfo symbol for a given module. */
680+ string_prepend (decl, "ModuleInfo for ");
681+ string_setlength (decl, string_length (decl) - 1);
682+ mangled += i + 1;
683+ return mangled;
684+ }
685+
686+ string_appendn (decl, mangled, i);
687+ mangled += i;
688+ }
689+ else
690+ return NULL;
691+
692+ return mangled;
693+}
694+
695+/* Extract the integer value from MANGLED and append it to DECL,
696+ where TYPE is the type it should be represented as.
697+ Return the remaining string on success or NULL on failure. */
698+static const char *
699+dlang_parse_integer (string *decl, const char *mangled, char type)
700+{
701+ if (type == 'a' || type == 'u' || type == 'w')
702+ {
703+ /* Parse character value. */
704+ char value[10];
705+ int pos = 10;
706+ int width = 0;
707+ char *endptr;
708+ long val = strtol (mangled, &endptr, 10);
709+
710+ if (endptr == NULL || val < 0)
711+ return NULL;
712+
713+ string_append (decl, "'");
714+
715+ if (type == 'a' && val >= 0x20 && val < 0x7F)
716+ {
717+ /* Represent as a character literal. */
718+ char c = (char) val;
719+ string_appendn (decl, &c, 1);
720+ }
721+ else
722+ {
723+ /* Represent as a hexadecimal value. */
724+ switch (type)
725+ {
726+ case 'a': /* char */
727+ string_append (decl, "\\x");
728+ width = 2;
729+ break;
730+ case 'u': /* wchar */
731+ string_append (decl, "\\u");
732+ width = 4;
733+ break;
734+ case 'w': /* dchar */
735+ string_append (decl, "\\U");
736+ width = 8;
737+ break;
738+ }
739+
740+ while (val > 0)
741+ {
742+ int digit = val % 16;
743+
744+ if (digit < 10)
745+ value[--pos] = (char)(digit + '0');
746+ else
747+ value[--pos] = (char)((digit - 10) + 'a');
748+
749+ val /= 16;
750+ width--;
751+ }
752+
753+ for (; width > 0; width--)
754+ value[--pos] = '0';
755+
756+ string_appendn (decl, &(value[pos]), 10 - pos);
757+ }
758+ string_append (decl, "'");
759+ mangled = endptr;
760+ }
761+ else if (type == 'b')
762+ {
763+ /* Parse boolean value. */
764+ char *endptr;
765+ long val = strtol (mangled, &endptr, 10);
766+
767+ if (endptr == NULL || val < 0)
768+ return NULL;
769+
770+ string_append (decl, val ? "true" : "false");
771+ mangled = endptr;
772+ }
773+ else
774+ {
775+ /* Parse integer value. */
776+ const char *numptr = mangled;
777+ size_t num = 0;
778+
779+ while (ISDIGIT (*mangled))
780+ {
781+ num++;
782+ mangled++;
783+ }
784+ string_appendn (decl, numptr, num);
785+
786+ /* Append suffix. */
787+ switch (type)
788+ {
789+ case 'h': /* ubyte */
790+ case 't': /* ushort */
791+ case 'k': /* uint */
792+ string_append (decl, "u");
793+ break;
794+ case 'l': /* long */
795+ string_append (decl, "L");
796+ break;
797+ case 'm': /* ulong */
798+ string_append (decl, "uL");
799+ break;
800+ }
801+ }
802+
803+ return mangled;
804+}
805+
806+/* Extract the floating-point value from MANGLED and append it to DECL.
807+ Return the remaining string on success or NULL on failure. */
808+static const char *
809+dlang_parse_real (string *decl, const char *mangled)
810+{
811+ char buffer[64];
812+ int len = 0;
813+ long double value;
814+ char *endptr;
815+
816+ /* Handle NAN and +-INF. */
817+ if (strncmp (mangled, "NAN", 3) == 0)
818+ {
819+ string_append (decl, "NaN");
820+ mangled += 3;
821+ return mangled;
822+ }
823+ else if (strncmp (mangled, "INF", 3) == 0)
824+ {
825+ string_append (decl, "Inf");
826+ mangled += 3;
827+ return mangled;
828+ }
829+ else if (strncmp (mangled, "NINF", 4) == 0)
830+ {
831+ string_append (decl, "-Inf");
832+ mangled += 4;
833+ return mangled;
834+ }
835+
836+ /* Hexadecimal prefix and leading bit. */
837+ if (*mangled == 'N')
838+ {
839+ buffer[len++] = '-';
840+ mangled++;
841+ }
842+
843+ if (!ISXDIGIT (*mangled))
844+ return NULL;
845+
846+ buffer[len++] = '0';
847+ buffer[len++] = 'x';
848+ buffer[len++] = *mangled;
849+ buffer[len++] = '.';
850+ mangled++;
851+
852+ /* Significand. */
853+ while (ISXDIGIT (*mangled))
854+ {
855+ buffer[len++] = *mangled;
856+ mangled++;
857+ }
858+
859+ /* Exponent. */
860+ if (*mangled != 'P')
861+ return NULL;
862+
863+ buffer[len++] = 'p';
864+ mangled++;
865+
866+ if (*mangled == 'N')
867+ {
868+ buffer[len++] = '-';
869+ mangled++;
870+ }
871+
872+ while (ISDIGIT (*mangled))
873+ {
874+ buffer[len++] = *mangled;
875+ mangled++;
876+ }
877+
878+ /* Convert buffer from hexadecimal to floating-point. */
879+ buffer[len] = '\0';
880+ value = strtold (buffer, &endptr);
881+
882+ if (endptr == NULL || endptr != (buffer + len))
883+ return NULL;
884+
885+ len = snprintf (buffer, sizeof(buffer), "%#Lg", value);
886+ string_appendn (decl, buffer, len);
887+ return mangled;
888+}
889+
890+/* Convert VAL from an ascii hexdigit to value. */
891+static char
892+ascii2hex (char val)
893+{
894+ if (val >= 'a' && val <= 'f')
895+ return (val - 'a' + 10);
896+
897+ if (val >= 'A' && val <= 'F')
898+ return (val - 'A' + 10);
899+
900+ if (val >= '0' && val <= '9')
901+ return (val - '0');
902+
903+ return 0;
904+}
905+
906+/* Extract the string value from MANGLED and append it to DECL.
907+ Return the remaining string on success or NULL on failure. */
908+static const char *
909+dlang_parse_string (string *decl, const char *mangled)
910+{
911+ char type = *mangled;
912+ char *endptr;
913+ long len;
914+
915+ mangled++;
916+ len = strtol (mangled, &endptr, 10);
917+
918+ if (endptr == NULL || len < 0)
919+ return NULL;
920+
921+ mangled = endptr;
922+ if (*mangled != '_')
923+ return NULL;
924+
925+ mangled++;
926+ string_append (decl, "\"");
927+ while (len--)
928+ {
929+ if (ISXDIGIT (mangled[0]) && ISXDIGIT (mangled[1]))
930+ {
931+ char a = ascii2hex (mangled[0]);
932+ char b = ascii2hex (mangled[1]);
933+ char val = (a << 4) | b;
934+ string_appendn (decl, &val, 1);
935+ }
936+ else
937+ return NULL;
938+
939+ mangled += 2;
940+ }
941+ string_append (decl, "\"");
942+
943+ if (type != 'a')
944+ string_appendn (decl, &type, 1);
945+
946+ return mangled;
947+}
948+
949+/* Extract the static array value from MANGLED and append it to DECL.
950+ Return the remaining string on success or NULL on failure. */
951+static const char *
952+dlang_parse_arrayliteral (string *decl, const char *mangled)
953+{
954+ char *endptr;
955+ long elements = strtol (mangled, &endptr, 10);
956+
957+ if (endptr == NULL || elements < 0)
958+ return NULL;
959+
960+ mangled = endptr;
961+ string_append (decl, "[");
962+ while (elements--)
963+ {
964+ mangled = dlang_value (decl, mangled, NULL, '\0');
965+ if (elements != 0)
966+ string_append (decl, ", ");
967+ }
968+
969+ string_append (decl, "]");
970+ return mangled;
971+}
972+
973+/* Extract the associative array value from MANGLED and append it to DECL.
974+ Return the remaining string on success or NULL on failure. */
975+static const char *
976+dlang_parse_assocarray (string *decl, const char *mangled)
977+{
978+ char *endptr;
979+ long elements = strtol (mangled, &endptr, 10);
980+
981+ if (endptr == NULL || elements < 0)
982+ return NULL;
983+
984+ mangled = endptr;
985+ string_append (decl, "[");
986+ while (elements--)
987+ {
988+ mangled = dlang_value (decl, mangled, NULL, '\0');
989+ string_append (decl, ":");
990+ mangled = dlang_value (decl, mangled, NULL, '\0');
991+
992+ if (elements != 0)
993+ string_append (decl, ", ");
994+ }
995+
996+ string_append (decl, "]");
997+ return mangled;
998+}
999+
1000+/* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1001+ Return the remaining string on success or NULL on failure. */
1002+static const char *
1003+dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1004+{
1005+ char *endptr;
1006+ long args = strtol (mangled, &endptr, 10);
1007+
1008+ if (endptr == NULL || args < 0)
1009+ return NULL;
1010+
1011+ mangled = endptr;
1012+ if (name != NULL)
1013+ string_append (decl, name);
1014+
1015+ string_append (decl, "(");
1016+ while (args--)
1017+ {
1018+ mangled = dlang_value (decl, mangled, NULL, '\0');
1019+ if (args != 0)
1020+ string_append (decl, ", ");
1021+ }
1022+
1023+ string_append (decl, ")");
1024+ return mangled;
1025+}
1026+
1027+/* Extract the value from MANGLED and append it to DECL.
1028+ Return the remaining string on success or NULL on failure. */
1029+static const char *
1030+dlang_value (string *decl, const char *mangled, const char *name, char type)
1031+{
1032+ if (mangled == NULL || *mangled == '\0')
1033+ return mangled;
1034+
1035+ switch (*mangled)
1036+ {
1037+ /* Null value. */
1038+ case 'n':
1039+ mangled++;
1040+ string_append (decl, "null");
1041+ break;
1042+
1043+ /* Integral values. */
1044+ case 'N':
1045+ mangled++;
1046+ string_append (decl, "-");
1047+ mangled = dlang_parse_integer (decl, mangled, type);
1048+ break;
1049+
1050+ case 'i':
1051+ mangled++;
1052+ if (*mangled < '0' || *mangled > '9')
1053+ return NULL;
1054+ /* Fall through */
1055+ case '0': case '1': case '2': case '3': case '4':
1056+ case '5': case '6': case '7': case '8': case '9':
1057+ mangled = dlang_parse_integer (decl, mangled, type);
1058+ break;
1059+
1060+ /* Real value. */
1061+ case 'e':
1062+ mangled++;
1063+ mangled = dlang_parse_real (decl, mangled);
1064+ break;
1065+
1066+ /* Complex value. */
1067+ case 'c':
1068+ mangled++;
1069+ mangled = dlang_parse_real (decl, mangled);
1070+ string_append (decl, "+");
1071+ if (mangled == NULL || *mangled != 'c')
1072+ return NULL;
1073+ mangled++;
1074+ mangled = dlang_parse_real (decl, mangled);
1075+ string_append (decl, "i");
1076+ break;
1077+
1078+ /* String values. */
1079+ case 'a': /* UTF8 */
1080+ case 'w': /* UTF16 */
1081+ case 'd': /* UTF32 */
1082+ mangled = dlang_parse_string (decl, mangled);
1083+ break;
1084+
1085+ /* Array values. */
1086+ case 'A':
1087+ mangled++;
1088+ if (type == 'H')
1089+ mangled = dlang_parse_assocarray (decl, mangled);
1090+ else
1091+ mangled = dlang_parse_arrayliteral (decl, mangled);
1092+ break;
1093+
1094+ /* Struct values. */
1095+ case 'S':
1096+ mangled++;
1097+ mangled = dlang_parse_structlit (decl, mangled, name);
1098+ break;
1099+
1100+ default:
1101+ return NULL;
1102+ }
1103+
1104+ return mangled;
1105+}
1106+
1107+static int
1108+dlang_call_convention_p (const char *mangled)
1109+{
1110+ size_t i;
1111+
1112+ switch (*mangled)
1113+ {
1114+ case 'F': case 'U': case 'V':
1115+ case 'W': case 'R':
1116+ return 1;
1117+
1118+ case 'M': /* Prefix for functions needing 'this' */
1119+ i = 1;
1120+ if (mangled[i] == 'x')
1121+ i++;
1122+
1123+ switch (mangled[i])
1124+ {
1125+ case 'F': case 'U': case 'V':
1126+ case 'W': case 'R':
1127+ return 1;
1128+ }
1129+
1130+ default:
1131+ return 0;
1132+ }
1133+}
1134+
1135+/* Extract and demangle the symbol in MANGLED and append it to DECL.
1136+ Returns the remaining signature on success or NULL on failure. */
1137+static const char *
1138+dlang_parse_symbol (string *decl, const char *mangled)
1139+{
1140+ size_t n = 0;
1141+ do
1142+ {
1143+ if (n++)
1144+ string_append (decl, ".");
1145+
1146+ mangled = dlang_identifier (decl, mangled);
1147+
1148+ if (mangled && dlang_call_convention_p (mangled))
1149+ {
1150+ int saved;
1151+
1152+ /* Skip over 'this' parameter. */
1153+ if (*mangled == 'M')
1154+ mangled += (mangled[1] == 'x') ? 2 : 1;
1155+
1156+ /* Skip over calling convention and attributes in qualified name. */
1157+ saved = string_length (decl);
1158+ mangled = dlang_call_convention (decl, mangled);
1159+ mangled = dlang_attributes (decl, mangled);
1160+ string_setlength (decl, saved);
1161+
1162+ string_append (decl, "(");
1163+ mangled = dlang_function_args (decl, mangled);
1164+ string_append (decl, ")");
1165+
1166+ /* Demangle the function return type as a kind of sanity test. */
1167+ if (mangled && !ISDIGIT (*mangled))
1168+ {
1169+ saved = string_length (decl);
1170+ mangled = dlang_type (decl, mangled);
1171+ string_setlength (decl, saved);
1172+ }
1173+ }
1174+ }
1175+ while (mangled && ISDIGIT (*mangled));
1176+
1177+ return mangled;
1178+}
1179+
1180+/* Demangle the tuple from MANGLED and append it to DECL.
1181+ Return the remaining string on success or NULL on failure. */
1182+static const char *
1183+dlang_parse_tuple (string *decl, const char *mangled)
1184+{
1185+ char *endptr;
1186+ long elements = strtol (mangled, &endptr, 10);
1187+
1188+ if (endptr == NULL || elements < 0)
1189+ return NULL;
1190+
1191+ mangled = endptr;
1192+ string_append (decl, "Tuple!(");
1193+
1194+ while (elements--)
1195+ {
1196+ mangled = dlang_type (decl, mangled);
1197+ if (elements != 0)
1198+ string_append (decl, ", ");
1199+ }
1200+
1201+ string_append (decl, ")");
1202+ return mangled;
1203+}
1204+
1205+/* Demangle the argument list from MANGLED and append it to DECL.
1206+ Return the remaining string on success or NULL on failure. */
1207+static const char *
1208+dlang_template_args (string *decl, const char *mangled)
1209+{
1210+ size_t n = 0;
1211+
1212+ while (mangled && *mangled != '\0')
1213+ {
1214+ switch (*mangled)
1215+ {
1216+ case 'Z': /* End of parameter list. */
1217+ mangled++;
1218+ return mangled;
1219+ }
1220+
1221+ if (n++)
1222+ string_append (decl, ", ");
1223+
1224+ switch (*mangled)
1225+ {
1226+ case 'S': /* Symbol parameter. */
1227+ mangled++;
1228+ mangled = dlang_parse_symbol (decl, mangled);
1229+ break;
1230+ case 'T': /* Type parameter. */
1231+ mangled++;
1232+ mangled = dlang_type (decl, mangled);
1233+ break;
1234+ case 'V': /* Value parameter. */
1235+ {
1236+ string name;
1237+ char type;
1238+
1239+ /* Peek at the type. */
1240+ mangled++;
1241+ type = *mangled;
1242+
1243+ /* In the few instances where the type is actually desired in
1244+ the output, it should precede the value from dlang_value. */
1245+ string_init (&name);
1246+ mangled = dlang_type (&name, mangled);
1247+ string_need (&name, 1);
1248+ *(name.p) = '\0';
1249+
1250+ mangled = dlang_value (decl, mangled, name.b, type);
1251+ string_delete (&name);
1252+ break;
1253+ }
1254+
1255+ default:
1256+ return NULL;
1257+ }
1258+ }
1259+
1260+ return mangled;
1261+}
1262+
1263+/* Extract and demangle the template symbol in MANGLED, expected to
1264+ be made up of LEN characters, and append it to DECL.
1265+ Returns the remaining signature on success or NULL on failure. */
1266+static const char *
1267+dlang_parse_template (string *decl, const char *mangled, long len)
1268+{
1269+ const char *start = mangled;
1270+
1271+ /* Template instance names have the types and values of its parameters
1272+ encoded into it.
1273+
1274+ TemplateInstanceName:
1275+ Number __T LName TemplateArgs Z
1276+ ^
1277+ The start pointer should be at the above location, and LEN should be
1278+ the value of the decoded number.
1279+ */
1280+ if (strncmp (mangled, "__T", 3) != 0)
1281+ return NULL;
1282+
1283+ mangled += 3;
1284+
1285+ /* Template identifier. */
1286+ mangled = dlang_identifier (decl, mangled);
1287+
1288+ /* Template arguments. */
1289+ string_append (decl, "!(");
1290+ mangled = dlang_template_args (decl, mangled);
1291+ string_append (decl, ")");
1292+
1293+ /* Check for template name length mismatch. */
1294+ if (mangled && (mangled - start) != len)
1295+ return NULL;
1296+
1297+ return mangled;
1298+}
1299+
1300+/* Extract and demangle the symbol in MANGLED. Returns the demangled
1301+ signature on success or NULL on failure. */
1302+
1303+char *
1304+dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1305+{
1306+ string decl;
1307+ char *demangled = NULL;
1308+
1309+ if (mangled == NULL || *mangled == '\0')
1310+ return NULL;
1311+
1312+ if (strncmp (mangled, "_D", 2) != 0)
1313+ return NULL;
1314+
1315+ string_init (&decl);
1316+
1317+ if (strcmp (mangled, "_Dmain") == 0)
1318+ {
1319+ string_append (&decl, "D main");
1320+ }
1321+ else
1322+ {
1323+ mangled += 2;
1324+
1325+ if (dlang_parse_symbol (&decl, mangled) == NULL)
1326+ string_delete (&decl);
1327+ }
1328+
1329+ if (string_length (&decl) > 0)
1330+ {
1331+ string_need (&decl, 1);
1332+ *(decl.p) = '\0';
1333+ demangled = decl.b;
1334+ }
1335+
1336+ return demangled;
1337+}
1338+
--- a/libiberty/pex-common.c
+++ b/libiberty/pex-common.c
@@ -267,7 +267,8 @@ pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
267267 if (out < 0)
268268 {
269269 out = obj->funcs->open_write (obj, outname,
270- (flags & PEX_BINARY_OUTPUT) != 0);
270+ (flags & PEX_BINARY_OUTPUT) != 0,
271+ (flags & PEX_STDOUT_APPEND) != 0);
271272 if (out < 0)
272273 {
273274 *err = errno;
@@ -319,8 +320,9 @@ pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
319320 }
320321 else
321322 {
322- errdes = obj->funcs->open_write (obj, errname,
323- (flags & PEX_BINARY_ERROR) != 0);
323+ errdes = obj->funcs->open_write (obj, errname,
324+ (flags & PEX_BINARY_ERROR) != 0,
325+ (flags & PEX_STDERR_APPEND) != 0);
324326 if (errdes < 0)
325327 {
326328 *err = errno;
--- a/libiberty/pex-common.h
+++ b/libiberty/pex-common.h
@@ -104,7 +104,7 @@ struct pex_funcs
104104 /* Open file NAME for writing. If BINARY is non-zero, open in
105105 binary mode. Return >= 0 on success, -1 on error. */
106106 int (*open_write) (struct pex_obj *, const char */* name */,
107- int /* binary */);
107+ int /* binary */, int /* append */);
108108 /* Execute a child process. FLAGS, EXECUTABLE, ARGV, ERR are from
109109 pex_run. IN, OUT, ERRDES, TOCLOSE are all descriptors, from
110110 open_read, open_write, or pipe, or they are one of STDIN_FILE_NO,
--- a/libiberty/pex-djgpp.c
+++ b/libiberty/pex-djgpp.c
@@ -43,7 +43,7 @@ extern int errno;
4343 #endif
4444
4545 static int pex_djgpp_open_read (struct pex_obj *, const char *, int);
46-static int pex_djgpp_open_write (struct pex_obj *, const char *, int);
46+static int pex_djgpp_open_write (struct pex_obj *, const char *, int, int);
4747 static pid_t pex_djgpp_exec_child (struct pex_obj *, int, const char *,
4848 char * const *, char * const *,
4949 int, int, int, int,
@@ -90,10 +90,12 @@ pex_djgpp_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED,
9090
9191 static int
9292 pex_djgpp_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED,
93- const char *name, int binary)
93+ const char *name, int binary, int append)
9494 {
9595 /* Note that we can't use O_EXCL here because gcc may have already
9696 created the temporary file via make_temp_file. */
97+ if (append)
98+ return -1;
9799 return open (name,
98100 (O_WRONLY | O_CREAT | O_TRUNC
99101 | (binary ? O_BINARY : O_TEXT)),
--- a/libiberty/pex-unix.c
+++ b/libiberty/pex-unix.c
@@ -301,7 +301,7 @@ pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
301301 static void pex_child_error (struct pex_obj *, const char *, const char *, int)
302302 ATTRIBUTE_NORETURN;
303303 static int pex_unix_open_read (struct pex_obj *, const char *, int);
304-static int pex_unix_open_write (struct pex_obj *, const char *, int);
304+static int pex_unix_open_write (struct pex_obj *, const char *, int, int);
305305 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
306306 char * const *, char * const *,
307307 int, int, int, int,
@@ -350,11 +350,12 @@ pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
350350
351351 static int
352352 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
353- int binary ATTRIBUTE_UNUSED)
353+ int binary ATTRIBUTE_UNUSED, int append)
354354 {
355355 /* Note that we can't use O_EXCL here because gcc may have already
356356 created the temporary file via make_temp_file. */
357- return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE);
357+ return open (name, O_WRONLY | O_CREAT
358+ | (append ? O_APPEND : O_TRUNC), PUBLIC_MODE);
358359 }
359360
360361 /* Close a file. */
--- a/libiberty/pex-win32.c
+++ b/libiberty/pex-win32.c
@@ -78,7 +78,7 @@ backslashify (char *s)
7878 }
7979
8080 static int pex_win32_open_read (struct pex_obj *, const char *, int);
81-static int pex_win32_open_write (struct pex_obj *, const char *, int);
81+static int pex_win32_open_write (struct pex_obj *, const char *, int, int);
8282 static pid_t pex_win32_exec_child (struct pex_obj *, int, const char *,
8383 char * const *, char * const *,
8484 int, int, int, int,
@@ -126,10 +126,12 @@ pex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
126126
127127 static int
128128 pex_win32_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
129- int binary)
129+ int binary, int append)
130130 {
131131 /* Note that we can't use O_EXCL here because gcc may have already
132132 created the temporary file via make_temp_file. */
133+ if (append)
134+ return -1;
133135 return _open (name,
134136 (_O_WRONLY | _O_CREAT | _O_TRUNC
135137 | (binary ? _O_BINARY : _O_TEXT)),
--- a/libiberty/simple-object-elf.c
+++ b/libiberty/simple-object-elf.c
@@ -698,6 +698,7 @@ simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
698698 unsigned char buf[sizeof (Elf64_External_Ehdr)];
699699 simple_object_write_section *section;
700700 unsigned int shnum;
701+ unsigned int shstrndx;
701702
702703 fns = attrs->type_functions;
703704 cl = attrs->ei_class;
@@ -743,9 +744,17 @@ simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
743744 (cl == ELFCLASS32
744745 ? sizeof (Elf32_External_Shdr)
745746 : sizeof (Elf64_External_Shdr)));
746- ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half, shnum);
747- ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half,
748- shnum == 0 ? 0 : shnum - 1);
747+ ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half,
748+ shnum >= SHN_LORESERVE ? 0 : shnum);
749+ if (shnum == 0)
750+ shstrndx = 0;
751+ else
752+ {
753+ shstrndx = shnum - 1;
754+ if (shstrndx >= SHN_LORESERVE)
755+ shstrndx = SHN_XINDEX;
756+ }
757+ ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, shstrndx);
749758
750759 return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
751760 errmsg, err);
@@ -758,8 +767,8 @@ simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
758767 off_t offset, unsigned int sh_name,
759768 unsigned int sh_type, unsigned int sh_flags,
760769 unsigned int sh_offset, unsigned int sh_size,
761- unsigned int sh_addralign, const char **errmsg,
762- int *err)
770+ unsigned int sh_link, unsigned int sh_addralign,
771+ const char **errmsg, int *err)
763772 {
764773 struct simple_object_elf_attributes *attrs =
765774 (struct simple_object_elf_attributes *) sobj->data;
@@ -781,7 +790,7 @@ simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
781790 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags);
782791 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset);
783792 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size);
784- /* sh_link left as zero. */
793+ ELF_SET_FIELD (fns, cl, Shdr, buf, sh_link, Elf_Word, sh_link);
785794 /* sh_info left as zero. */
786795 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign);
787796 /* sh_entsize left as zero. */
@@ -812,6 +821,8 @@ simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
812821 unsigned int shnum;
813822 size_t shdr_offset;
814823 size_t sh_offset;
824+ unsigned int first_sh_size;
825+ unsigned int first_sh_link;
815826 size_t sh_name;
816827 unsigned char zero;
817828
@@ -842,8 +853,17 @@ simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
842853 shdr_offset = ehdr_size;
843854 sh_offset = shdr_offset + shnum * shdr_size;
844855
856+ if (shnum < SHN_LORESERVE)
857+ first_sh_size = 0;
858+ else
859+ first_sh_size = shnum;
860+ if (shnum - 1 < SHN_LORESERVE)
861+ first_sh_link = 0;
862+ else
863+ first_sh_link = shnum - 1;
845864 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
846- 0, 0, 0, 0, 0, 0, &errmsg, err))
865+ 0, 0, 0, 0, first_sh_size, first_sh_link,
866+ 0, &errmsg, err))
847867 return errmsg;
848868
849869 shdr_offset += shdr_size;
@@ -887,7 +907,7 @@ simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
887907
888908 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
889909 sh_name, SHT_PROGBITS, 0, sh_offset,
890- sh_size, 1U << section->align,
910+ sh_size, 0, 1U << section->align,
891911 &errmsg, err))
892912 return errmsg;
893913
@@ -898,7 +918,7 @@ simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
898918
899919 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
900920 sh_name, SHT_STRTAB, 0, sh_offset,
901- sh_name + strlen (".shstrtab") + 1,
921+ sh_name + strlen (".shstrtab") + 1, 0,
902922 1, &errmsg, err))
903923 return errmsg;
904924
--- a/libiberty/testsuite/Makefile.in
+++ b/libiberty/testsuite/Makefile.in
@@ -45,12 +45,15 @@ all:
4545 # CHECK is set to "really_check" or the empty string by configure.
4646 check: @CHECK@
4747
48-really-check: check-cplus-dem check-pexecute check-expandargv
48+really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv
4949
5050 # Run some tests of the demangler.
5151 check-cplus-dem: test-demangle $(srcdir)/demangle-expected
5252 ./test-demangle < $(srcdir)/demangle-expected
5353
54+check-d-demangle: test-demangle $(srcdir)/d-demangle-expected
55+ ./test-demangle < $(srcdir)/d-demangle-expected
56+
5457 # Check the pexecute code.
5558 check-pexecute: test-pexecute
5659 ./test-pexecute
@@ -59,6 +62,10 @@ check-pexecute: test-pexecute
5962 check-expandargv: test-expandargv
6063 ./test-expandargv
6164
65+# Run the demangler fuzzer
66+fuzz-demangler: demangler-fuzzer
67+ ./demangler-fuzzer
68+
6269 TEST_COMPILE = $(CC) @DEFS@ $(LIBCFLAGS) -I.. -I$(INCDIR) $(HDEFINES)
6370 test-demangle: $(srcdir)/test-demangle.c ../libiberty.a
6471 $(TEST_COMPILE) -o test-demangle \
@@ -72,6 +79,10 @@ test-expandargv: $(srcdir)/test-expandargv.c ../libiberty.a
7279 $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-expandargv \
7380 $(srcdir)/test-expandargv.c ../libiberty.a
7481
82+demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a
83+ $(TEST_COMPILE) -o demangler-fuzzer \
84+ $(srcdir)/demangler-fuzzer.c ../libiberty.a
85+
7586 # Standard (either GNU or Cygnus) rules we don't use.
7687 html install-html info install-info clean-info dvi pdf install-pdf \
7788 install etags tags installcheck:
@@ -81,6 +92,7 @@ mostlyclean:
8192 rm -f test-demangle
8293 rm -f test-pexecute
8394 rm -f test-expandargv
95+ rm -f demangler-fuzzer
8496 rm -f core
8597 clean: mostlyclean
8698 distclean: clean
--- /dev/null
+++ b/libiberty/testsuite/d-demangle-expected
@@ -0,0 +1,936 @@
1+# This file holds test cases for the D demangler.
2+# Each test case looks like this:
3+# options
4+# input to be demangled
5+# expected output
6+#
7+# See demangle-expected for documentation of supported options.
8+#
9+# A line starting with `#' is ignored.
10+# However, blank lines in this file are NOT ignored.
11+#
12+############
13+#
14+# Coverage Tests
15+#
16+--format=dlang
17+_Dmain
18+D main
19+#
20+--format=dlang
21+_D8demangle4testPFLAiYi
22+demangle.test
23+#
24+--format=dlang
25+_D8demangle4testFaZv
26+demangle.test(char)
27+#
28+--format=dlang
29+_D8demangle4testFbZv
30+demangle.test(bool)
31+#
32+--format=dlang
33+_D8demangle4testFcZv
34+demangle.test(creal)
35+#
36+--format=dlang
37+_D8demangle4testFdZv
38+demangle.test(double)
39+#
40+--format=dlang
41+_D8demangle4testFeZv
42+demangle.test(real)
43+#
44+--format=dlang
45+_D8demangle4testFfZv
46+demangle.test(float)
47+#
48+--format=dlang
49+_D8demangle4testFgZv
50+demangle.test(byte)
51+#
52+--format=dlang
53+_D8demangle4testFhZv
54+demangle.test(ubyte)
55+#
56+--format=dlang
57+_D8demangle4testFiZv
58+demangle.test(int)
59+#
60+--format=dlang
61+_D8demangle4testFjZv
62+demangle.test(ireal)
63+#
64+--format=dlang
65+_D8demangle4testFkZv
66+demangle.test(uint)
67+#
68+--format=dlang
69+_D8demangle4testFlZv
70+demangle.test(long)
71+#
72+--format=dlang
73+_D8demangle4testFmZv
74+demangle.test(ulong)
75+#
76+--format=dlang
77+_D8demangle4testFnZv
78+demangle.test(none)
79+#
80+--format=dlang
81+_D8demangle4testFoZv
82+demangle.test(ifloat)
83+#
84+--format=dlang
85+_D8demangle4testFpZv
86+demangle.test(idouble)
87+#
88+--format=dlang
89+_D8demangle4testFqZv
90+demangle.test(cfloat)
91+#
92+--format=dlang
93+_D8demangle4testFrZv
94+demangle.test(cdouble)
95+#
96+--format=dlang
97+_D8demangle4testFsZv
98+demangle.test(short)
99+#
100+--format=dlang
101+_D8demangle4testFtZv
102+demangle.test(ushort)
103+#
104+--format=dlang
105+_D8demangle4testFuZv
106+demangle.test(wchar)
107+#
108+--format=dlang
109+_D8demangle4testFvZv
110+demangle.test(void)
111+#
112+--format=dlang
113+_D8demangle4testFwZv
114+demangle.test(dchar)
115+#
116+--format=dlang
117+_D8demangle4testFOaZv
118+demangle.test(shared(char))
119+#
120+--format=dlang
121+_D8demangle4testFxaZv
122+demangle.test(const(char))
123+#
124+--format=dlang
125+_D8demangle4testFyaZv
126+demangle.test(immutable(char))
127+#
128+--format=dlang
129+_D8demangle4testFNgaZv
130+demangle.test(inout(char))
131+#
132+--format=dlang
133+_D8demangle4testFOxaZv
134+demangle.test(shared(const(char)))
135+#
136+--format=dlang
137+_D8demangle4testFONgaZv
138+demangle.test(shared(inout(char)))
139+#
140+--format=dlang
141+_D8demangle4testFAaZv
142+demangle.test(char[])
143+#
144+--format=dlang
145+_D8demangle4testFAAaZv
146+demangle.test(char[][])
147+#
148+--format=dlang
149+_D8demangle4testFAAAaZv
150+demangle.test(char[][][])
151+#
152+--format=dlang
153+_D8demangle4testFG42aZv
154+demangle.test(char[42])
155+#
156+--format=dlang
157+_D8demangle4testFG42G42aZv
158+demangle.test(char[42][42])
159+#
160+--format=dlang
161+_D8demangle4testFG42G42G42aZv
162+demangle.test(char[42][42][42])
163+#
164+--format=dlang
165+_D8demangle4testFG1234567890aZv
166+demangle.test(char[1234567890])
167+#
168+--format=dlang
169+_D8demangle4testFHaaZv
170+demangle.test(char[char])
171+#
172+--format=dlang
173+_D8demangle4testFHHaaaZv
174+demangle.test(char[char[char]])
175+#
176+--format=dlang
177+_D8demangle4testFPaZv
178+demangle.test(char*)
179+#
180+--format=dlang
181+_D8demangle4testFPPaZv
182+demangle.test(char**)
183+#
184+--format=dlang
185+_D8demangle4testFPPPaZv
186+demangle.test(char***)
187+#
188+--format=dlang
189+_D8demangle4testFNhG8gZv
190+demangle.test(__vector(byte[8]))
191+#
192+--format=dlang
193+_D8demangle4testFNhG16gZv
194+demangle.test(__vector(byte[16]))
195+#
196+--format=dlang
197+_D8demangle4testFNhG32gZv
198+demangle.test(__vector(byte[32]))
199+#
200+--format=dlang
201+_D8demangle4testFNhG4sZv
202+demangle.test(__vector(short[4]))
203+#
204+--format=dlang
205+_D8demangle4testFNhG8sZv
206+demangle.test(__vector(short[8]))
207+#
208+--format=dlang
209+_D8demangle4testFNhG16sZv
210+demangle.test(__vector(short[16]))
211+#
212+--format=dlang
213+_D8demangle4testFNhG2iZv
214+demangle.test(__vector(int[2]))
215+#
216+--format=dlang
217+_D8demangle4testFNhG4iZv
218+demangle.test(__vector(int[4]))
219+#
220+--format=dlang
221+_D8demangle4testFNhG8iZv
222+demangle.test(__vector(int[8]))
223+#
224+--format=dlang
225+_D8demangle4testFNhG1lZv
226+demangle.test(__vector(long[1]))
227+#
228+--format=dlang
229+_D8demangle4testFNhG2lZv
230+demangle.test(__vector(long[2]))
231+#
232+--format=dlang
233+_D8demangle4testFNhG4lZv
234+demangle.test(__vector(long[4]))
235+#
236+--format=dlang
237+_D8demangle4testFNhG2fZv
238+demangle.test(__vector(float[2]))
239+#
240+--format=dlang
241+_D8demangle4testFNhG4fZv
242+demangle.test(__vector(float[4]))
243+#
244+--format=dlang
245+_D8demangle4testFNhG8fZv
246+demangle.test(__vector(float[8]))
247+#
248+--format=dlang
249+_D8demangle4testFNhG1dZv
250+demangle.test(__vector(double[1]))
251+#
252+--format=dlang
253+_D8demangle4testFNhG2dZv
254+demangle.test(__vector(double[2]))
255+#
256+--format=dlang
257+_D8demangle4testFNhG4dZv
258+demangle.test(__vector(double[4]))
259+#
260+--format=dlang
261+_D8demangle4testFI5identZv
262+demangle.test(ident)
263+#
264+--format=dlang
265+_D8demangle4testFI5ident4testZv
266+demangle.test(ident.test)
267+#
268+--format=dlang
269+_D8demangle4testFC5classZv
270+demangle.test(class)
271+#
272+--format=dlang
273+_D8demangle4testFC5class4testZv
274+demangle.test(class.test)
275+#
276+--format=dlang
277+_D8demangle4testFS6structZv
278+demangle.test(struct)
279+#
280+--format=dlang
281+_D8demangle4testFS6struct4testZv
282+demangle.test(struct.test)
283+#
284+--format=dlang
285+_D8demangle4testFE4enumZv
286+demangle.test(enum)
287+#
288+--format=dlang
289+_D8demangle4testFE4enum4testZv
290+demangle.test(enum.test)
291+#
292+--format=dlang
293+_D8demangle4testFT7typedefZv
294+demangle.test(typedef)
295+#
296+--format=dlang
297+_D8demangle4testFT7typedef4testZv
298+demangle.test(typedef.test)
299+#
300+--format=dlang
301+_D8demangle4testFJaZv
302+demangle.test(out char)
303+#
304+--format=dlang
305+_D8demangle4testFKaZv
306+demangle.test(ref char)
307+#
308+--format=dlang
309+_D8demangle4testFLaZv
310+demangle.test(lazy char)
311+#
312+--format=dlang
313+_D8demangle4testFMaZv
314+demangle.test(scope char)
315+#
316+--format=dlang
317+_D8demangle4testFaXv
318+demangle.test(char...)
319+#
320+--format=dlang
321+_D8demangle4testFaYv
322+demangle.test(char, ...)
323+#
324+--format=dlang
325+_D8demangle4testFaaYv
326+demangle.test(char, char, ...)
327+#
328+--format=dlang
329+_D8demangle4testFaaZv
330+demangle.test(char, char)
331+#
332+--format=dlang
333+_D8demangle4testFB0Zv
334+demangle.test(Tuple!())
335+#
336+--format=dlang
337+_D8demangle4testFB1aZv
338+demangle.test(Tuple!(char))
339+#
340+--format=dlang
341+_D8demangle4testFB2aaZv
342+demangle.test(Tuple!(char, char))
343+#
344+--format=dlang
345+_D8demangle4testFB3aaaZv
346+demangle.test(Tuple!(char, char, char))
347+#
348+--format=dlang
349+_D8demangle4testFB2OaaZv
350+demangle.test(Tuple!(shared(char), char))
351+#
352+--format=dlang
353+_D8demangle4testFB3aDFZaaZv
354+demangle.test(Tuple!(char, char() delegate, char))
355+#
356+--format=dlang
357+_D8demangle4testFDFZaZv
358+demangle.test(char() delegate)
359+#
360+--format=dlang
361+_D8demangle4testFDUZaZv
362+demangle.test(extern(C) char() delegate)
363+#
364+--format=dlang
365+_D8demangle4testFDWZaZv
366+demangle.test(extern(Windows) char() delegate)
367+#
368+--format=dlang
369+_D8demangle4testFDVZaZv
370+demangle.test(extern(Pascal) char() delegate)
371+#
372+--format=dlang
373+_D8demangle4testFDRZaZv
374+demangle.test(extern(C++) char() delegate)
375+#
376+--format=dlang
377+_D8demangle4testFFZaZv
378+demangle.test(char() function)
379+#
380+--format=dlang
381+_D8demangle4testFUZaZv
382+demangle.test(extern(C) char() function)
383+#
384+--format=dlang
385+_D8demangle4testFWZaZv
386+demangle.test(extern(Windows) char() function)
387+#
388+--format=dlang
389+_D8demangle4testFVZaZv
390+demangle.test(extern(Pascal) char() function)
391+#
392+--format=dlang
393+_D8demangle4testFRZaZv
394+demangle.test(extern(C++) char() function)
395+#
396+--format=dlang
397+_D8demangle4testFDFNaZaZv
398+demangle.test(char() pure delegate)
399+#
400+--format=dlang
401+_D8demangle4testFDFNbZaZv
402+demangle.test(char() nothrow delegate)
403+#
404+--format=dlang
405+_D8demangle4testFDFNcZaZv
406+demangle.test(char() ref delegate)
407+#
408+--format=dlang
409+_D8demangle4testFDFNdZaZv
410+demangle.test(char() @property delegate)
411+#
412+--format=dlang
413+_D8demangle4testFDFNeZaZv
414+demangle.test(char() @trusted delegate)
415+#
416+--format=dlang
417+_D8demangle4testFDFNfZaZv
418+demangle.test(char() @safe delegate)
419+#
420+--format=dlang
421+_D8demangle4testFDFNiZaZv
422+demangle.test(char() @nogc delegate)
423+#
424+--format=dlang
425+_D8demangle4testFDFNaNbZaZv
426+demangle.test(char() pure nothrow delegate)
427+#
428+--format=dlang
429+_D8demangle4testFDFNbNaZaZv
430+demangle.test(char() nothrow pure delegate)
431+#
432+--format=dlang
433+_D8demangle4testFDFNdNfNaZaZv
434+demangle.test(char() @property @safe pure delegate)
435+#
436+--format=dlang
437+_D8demangle4testFFNaZaZv
438+demangle.test(char() pure function)
439+#
440+--format=dlang
441+_D8demangle4testFFNbZaZv
442+demangle.test(char() nothrow function)
443+#
444+--format=dlang
445+_D8demangle4testFFNcZaZv
446+demangle.test(char() ref function)
447+#
448+--format=dlang
449+_D8demangle4testFFNdZaZv
450+demangle.test(char() @property function)
451+#
452+--format=dlang
453+_D8demangle4testFFNeZaZv
454+demangle.test(char() @trusted function)
455+#
456+--format=dlang
457+_D8demangle4testFFNfZaZv
458+demangle.test(char() @safe function)
459+#
460+--format=dlang
461+_D8demangle4testFFNiZaZv
462+demangle.test(char() @nogc function)
463+#
464+--format=dlang
465+_D8demangle4testFFNaNbZaZv
466+demangle.test(char() pure nothrow function)
467+#
468+--format=dlang
469+_D8demangle4testFFNbNaZaZv
470+demangle.test(char() nothrow pure function)
471+#
472+--format=dlang
473+_D8demangle4testFFNdNfNaZaZv
474+demangle.test(char() @property @safe pure function)
475+#
476+--format=dlang
477+_D8demangle4test6__initZ
478+demangle.test.init$
479+#
480+--format=dlang
481+_D8demangle4test6__vtblZ
482+vtable for demangle.test
483+#
484+--format=dlang
485+_D8demangle4test7__ClassZ
486+ClassInfo for demangle.test
487+#
488+--format=dlang
489+_D8demangle4test11__InterfaceZ
490+Interface for demangle.test
491+#
492+--format=dlang
493+_D8demangle4test12__ModuleInfoZ
494+ModuleInfo for demangle.test
495+#
496+--format=dlang
497+_D8demangle4test6__ctorMFZv
498+demangle.test.this()
499+#
500+--format=dlang
501+_D8demangle4test6__dtorMFZv
502+demangle.test.~this()
503+#
504+--format=dlang
505+_D8demangle4test6__postblitMFZv
506+demangle.test.this(this)
507+#
508+--format=dlang
509+_D8demangle4testFHAbaZv
510+demangle.test(char[bool[]])
511+#
512+--format=dlang
513+_D8demangle4testFHG42caZv
514+demangle.test(char[creal[42]])
515+#
516+--format=dlang
517+_D8demangle4testFAiXv
518+demangle.test(int[]...)
519+#
520+--format=dlang
521+_D8demangle4testFLAiXv
522+demangle.test(lazy int[]...)
523+#
524+--format=dlang
525+_D8demangle4testFAiYv
526+demangle.test(int[], ...)
527+#
528+--format=dlang
529+_D8demangle4testFLAiYv
530+demangle.test(lazy int[], ...)
531+#
532+--format=dlang
533+_D8demangle4testFLilZv
534+demangle.test(lazy int, long)
535+#
536+--format=dlang
537+_D8demangle4testFLliZv
538+demangle.test(lazy long, int)
539+#
540+--format=dlang
541+_D8demangle4testFLC6ObjectLDFLiZiZi
542+demangle.test(lazy Object, lazy int(lazy int) delegate)
543+#
544+--format=dlang
545+_D8demangle9__T4testZv
546+demangle.test!()
547+#
548+--format=dlang
549+_D8demangle11__T4testTaZv
550+demangle.test!(char)
551+#
552+--format=dlang
553+_D8demangle13__T4testTaTaZv
554+demangle.test!(char, char)
555+#
556+--format=dlang
557+_D8demangle15__T4testTaTaTaZv
558+demangle.test!(char, char, char)
559+#
560+--format=dlang
561+_D8demangle16__T4testTaTOiTaZv
562+demangle.test!(char, shared(int), char)
563+#
564+--format=dlang
565+_D8demangle17__T4testS6symbolZv
566+demangle.test!(symbol)
567+#
568+--format=dlang
569+_D8demangle21__T4testS6symbol3fooZv
570+demangle.test!(symbol.foo)
571+#
572+--format=dlang
573+_D8demangle25__T4testS6symbol3foo3barZv
574+demangle.test!(symbol.foo.bar)
575+#
576+--format=dlang
577+_D8demangle19__T4testTaS6symbolZv
578+demangle.test!(char, symbol)
579+#
580+--format=dlang
581+_D8demangle19__T4testS6symbolTaZv
582+demangle.test!(symbol, char)
583+#
584+--format=dlang
585+_D8demangle13__T4testVPinZv
586+demangle.test!(null)
587+#
588+--format=dlang
589+_D8demangle14__T4testVg123Zv
590+demangle.test!(123)
591+#
592+--format=dlang
593+_D8demangle14__T4testVi123Zv
594+demangle.test!(123)
595+#
596+--format=dlang
597+_D8demangle14__T4testVs123Zv
598+demangle.test!(123)
599+#
600+--format=dlang
601+_D8demangle14__T4testVh123Zv
602+demangle.test!(123u)
603+#
604+--format=dlang
605+_D8demangle14__T4testVk123Zv
606+demangle.test!(123u)
607+#
608+--format=dlang
609+_D8demangle14__T4testVt123Zv
610+demangle.test!(123u)
611+#
612+--format=dlang
613+_D8demangle14__T4testVl123Zv
614+demangle.test!(123L)
615+#
616+--format=dlang
617+_D8demangle14__T4testVm123Zv
618+demangle.test!(123uL)
619+#
620+--format=dlang
621+_D8demangle15__T4testViN123Zv
622+demangle.test!(-123)
623+#
624+--format=dlang
625+_D8demangle15__T4testVkN123Zv
626+demangle.test!(-123u)
627+#
628+--format=dlang
629+_D8demangle15__T4testVlN123Zv
630+demangle.test!(-123L)
631+#
632+--format=dlang
633+_D8demangle15__T4testVmN123Zv
634+demangle.test!(-123uL)
635+#
636+--format=dlang
637+_D8demangle12__T4testVb1Zv
638+demangle.test!(true)
639+#
640+--format=dlang
641+_D8demangle12__T4testVb0Zv
642+demangle.test!(false)
643+#
644+--format=dlang
645+_D8demangle13__T4testVa10Zv
646+demangle.test!('\x0a')
647+#
648+--format=dlang
649+_D8demangle13__T4testVa32Zv
650+demangle.test!(' ')
651+#
652+--format=dlang
653+_D8demangle13__T4testVa65Zv
654+demangle.test!('A')
655+#
656+--format=dlang
657+_D8demangle14__T4testVa126Zv
658+demangle.test!('~')
659+#
660+--format=dlang
661+_D8demangle15__T4testVu1000Zv
662+demangle.test!('\u03e8')
663+#
664+--format=dlang
665+_D8demangle17__T4testVw100000Zv
666+demangle.test!('\U000186a0')
667+#
668+--format=dlang
669+_D8demangle17__T4testVde0A8P6Zv
670+demangle.test!(42.0000)
671+#
672+--format=dlang
673+_D8demangle16__T4testVdeA8P2Zv
674+demangle.test!(42.0000)
675+#
676+--format=dlang
677+_D8demangle18__T4testVdeN0A8P6Zv
678+demangle.test!(-42.0000)
679+#
680+--format=dlang
681+_D8demangle31__T4testVde0F6E978D4FDF3B646P7Zv
682+demangle.test!(123.456)
683+#
684+--format=dlang
685+_D8demangle15__T4testVdeNANZv
686+demangle.test!(NaN)
687+#
688+--format=dlang
689+_D8demangle15__T4testVdeINFZv
690+demangle.test!(Inf)
691+#
692+--format=dlang
693+_D8demangle16__T4testVdeNINFZv
694+demangle.test!(-Inf)
695+#
696+--format=dlang
697+_D8demangle23__T4testVfe0FFFFFFP128Zv
698+demangle.test!(3.40282e+38)
699+#
700+--format=dlang
701+_D8demangle32__T4testVde0FFFFFFFFFFFFF8P1024Zv
702+demangle.test!(1.79769e+308)
703+#
704+--format=dlang
705+_D8demangle19__T4testVfe08PN125Zv
706+demangle.test!(1.17549e-38)
707+#
708+--format=dlang
709+_D8demangle20__T4testVde08PN1021Zv
710+demangle.test!(2.22507e-308)
711+#
712+--format=dlang
713+_D8demangle51__T4testVrc0C4CCCCCCCCCCCCCDP4c0B666666666666666P6Zv
714+demangle.test!(12.3000+45.6000i)
715+#
716+--format=dlang
717+_D8demangle52__T4testVrcN0C4CCCCCCCCCCCCCDP4c0B666666666666666P6Zv
718+demangle.test!(-12.3000+45.6000i)
719+#
720+--format=dlang
721+_D8demangle22__T4testVG3ua3_616263Zv
722+demangle.test!("abc")
723+#
724+--format=dlang
725+_D8demangle22__T4testVG3ud3_616263Zv
726+demangle.test!("abc"d)
727+#
728+--format=dlang
729+_D8demangle22__T4testVG3uw3_616263Zv
730+demangle.test!("abc"w)
731+#
732+--format=dlang
733+_D8demangle22__T4testVAiA4i1i2i3i4Zv
734+demangle.test!([1, 2, 3, 4])
735+#
736+--format=dlang
737+_D8demangle25__T4testVAdA2e08P1eN08P1Zv
738+demangle.test!([1.00000, -1.00000])
739+#
740+--format=dlang
741+_D8demangle23__T4testVHiiA2i1i2i3i4Zv
742+demangle.test!([1:2, 3:4])
743+#
744+--format=dlang
745+_D8demangle39__T4testVHAxaiA2a3_616263i1a3_646566i2Zv
746+demangle.test!(["abc":1, "def":2])
747+#
748+--format=dlang
749+_D8demangle28__T4testVS8demangle1SS2i1i2Zv
750+demangle.test!(demangle.S(1, 2))
751+#
752+--format=dlang
753+_D8demangle35__T4testVS8demangle1SS2i1a3_616263Zv
754+demangle.test!(demangle.S(1, "abc"))
755+#
756+# Unittests
757+#
758+--format=dlang
759+printf
760+printf
761+#
762+--format=dlang
763+_foo
764+_foo
765+#
766+--format=dlang
767+_D88
768+_D88
769+#
770+--format=dlang
771+_D5__T1aZv
772+_D5__T1aZv
773+#
774+--format=dlang
775+_D4test3fooAa
776+test.foo
777+#
778+--format=dlang
779+_D8demangle8demangleFAaZAa
780+demangle.demangle(char[])
781+#
782+--format=dlang
783+_D6object6Object8opEqualsFC6ObjectZi
784+object.Object.opEquals(Object)
785+#
786+--format=dlang
787+_D6object6Object8opAssignFC6ObjectZi
788+object.Object.opAssign(Object)
789+#
790+--format=dlang
791+_D4test2dgDFiYd
792+test.dg
793+#
794+--format=dlang
795+_D1a1bi
796+a.b
797+#
798+--format=dlang
799+_D1a1bPFiZi
800+a.b
801+#
802+--format=dlang
803+_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi
804+test.bar!("abc"w, "def"d).x
805+#
806+--format=dlang
807+_D6plugin8generateFiiZAya
808+plugin.generate(int, int)
809+#
810+--format=dlang
811+_D6plugin8generateFiiZAxa
812+plugin.generate(int, int)
813+#
814+--format=dlang
815+_D6plugin8generateFiiZAOa
816+plugin.generate(int, int)
817+#
818+--format=dlang
819+_D8demangle3fnAFZv3fnBMFZv
820+demangle.fnA().fnB()
821+#
822+--format=dlang
823+_D8demangle4mainFZv1S3fnCFZv
824+demangle.main().S.fnC()
825+#
826+--format=dlang
827+_D8demangle4mainFZv1S3fnDMFZv
828+demangle.main().S.fnD()
829+#
830+--format=dlang
831+_D8demangle4mainFZv5localMFZi
832+demangle.main().local()
833+#
834+--format=dlang
835+_D3std5ascii9uppercaseyAa
836+std.ascii.uppercase
837+#
838+--format=dlang
839+_D3std6stream9BOMEndianyG5E3std6system6Endian
840+std.stream.BOMEndian
841+#
842+--format=dlang
843+_D3std8internal7uni_tab10unicodeNkoyS3std8internal3uni12CodepointSet
844+std.internal.uni_tab.unicodeNko
845+#
846+--format=dlang
847+_D2gc2gc2GC6addrOfMFPvZPv
848+gc.gc.GC.addrOf(void*)
849+#
850+--format=dlang
851+_D3std7process10setCLOEXECFibZv
852+std.process.setCLOEXEC(int, bool)
853+#
854+--format=dlang
855+_D3std6digest2md3MD53putMFNaNbNeMAxhXv
856+std.digest.md.MD5.put(scope const(ubyte)[]...)
857+#
858+--format=dlang
859+_D3std6mmfile6MmFile13opIndexAssignMFhmZh
860+std.mmfile.MmFile.opIndexAssign(ubyte, ulong)
861+#
862+--format=dlang
863+_D3std7process18escapeShellCommandFxAAaXAya
864+std.process.escapeShellCommand(const(char[][])...)
865+#
866+--format=dlang
867+_D4core4sync5mutex5Mutex6__ctorMFC6ObjectZC4core4sync5mutex5Mutex
868+core.sync.mutex.Mutex.this(Object)
869+#
870+--format=dlang
871+_D6object14TypeInfo_Array8argTypesMFNbNfJC8TypeInfoJC8TypeInfoZi
872+object.TypeInfo_Array.argTypes(out TypeInfo, out TypeInfo)
873+#
874+--format=dlang
875+_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7tryExecMFMDFZvZv
876+rt.dmain2._d_run_main(int, char**, extern(C) int(char[][]) function*).tryExec(scope void() delegate)
877+#
878+--format=dlang
879+_D6object9Exception6__ctorMFNaNbNfAyaAyamC6object9ThrowableZC9Exception
880+object.Exception.this(immutable(char)[], immutable(char)[], ulong, object.Throwable)
881+#
882+--format=dlang
883+_D3gcc3deh17parse_lsda_headerFPS3gcc6unwind7generic15_Unwind_ContextPhPS3gcc3deh16lsda_header_infoZPh
884+gcc.deh.parse_lsda_header(gcc.unwind.generic._Unwind_Context*, ubyte*, gcc.deh.lsda_header_info*)
885+#
886+--format=dlang
887+_D3std6socket23UnknownAddressReference6__ctorMFPS4core3sys5posix3sys6socket8sockaddrkZC3std6socket23UnknownAddressReference
888+std.socket.UnknownAddressReference.this(core.sys.posix.sys.socket.sockaddr*, uint)
889+#
890+--format=dlang
891+_D8demangle20__T2fnVAiA4i1i2i3i4Z2fnFZv
892+demangle.fn!([1, 2, 3, 4]).fn()
893+#
894+--format=dlang
895+_D8demangle10__T2fnVi1Z2fnFZv
896+demangle.fn!(1).fn()
897+#
898+--format=dlang
899+_D8demangle26__T2fnVS8demangle1SS2i1i2Z2fnFZv
900+demangle.fn!(demangle.S(1, 2)).fn()
901+#
902+--format=dlang
903+_D8demangle13__T2fnVeeNANZ2fnFZv
904+demangle.fn!(NaN).fn()
905+#
906+--format=dlang
907+_D8demangle14__T2fnVeeNINFZ2fnFZv
908+demangle.fn!(-Inf).fn()
909+#
910+--format=dlang
911+_D8demangle13__T2fnVeeINFZ2fnFZv
912+demangle.fn!(Inf).fn()
913+#
914+--format=dlang
915+_D8demangle21__T2fnVHiiA2i1i2i3i4Z2fnFZv
916+demangle.fn!([1:2, 3:4]).fn()
917+#
918+--format=dlang
919+_D8demangle2fnFNgiZNgi
920+demangle.fn(inout(int))
921+#
922+--format=dlang
923+_D8demangle29__T2fnVa97Va9Va0Vu257Vw65537Z2fnFZv
924+demangle.fn!('a', '\x09', '\x00', '\u0101', '\U00010001').fn()
925+#
926+--format=dlang
927+_D2gc11gctemplates56__T8mkBitmapTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ8mkBitmapFNbNiNfPmmZv
928+gc.gctemplates.mkBitmap!(std.range.iota!(int, int).iota(int, int).Result).mkBitmap(ulong*, ulong)
929+#
930+--format=dlang
931+_D8serenity9persister6Sqlite70__T15SqlitePersisterTS8serenity9persister6Sqlite11__unittest6FZv4TestZ15SqlitePersister12__T7opIndexZ7opIndexMFmZS8serenity9persister6Sqlite11__unittest6FZv4Test
932+serenity.persister.Sqlite.SqlitePersister!(serenity.persister.Sqlite.__unittest6().Test).SqlitePersister.opIndex!().opIndex(ulong)
933+#
934+--format=dlang
935+_D4test4mainFZv5localMFZi
936+test.main().local()
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4343,8 +4343,16 @@ cereal::detail::InputBindingMap<cereal::JSONInputArchive>::Serializers cereal::p
43434343 --format=gnu-v3
43444344 _ZNSt9_Any_data9_M_accessIPZ4postISt8functionIFvvEEEvOT_EUlvE_EERS5_v
43454345 void post<std::function<void ()> >(std::function<void ()>&&)::{lambda()#1}*& std::_Any_data::_M_access<void post<std::function<void ()> >(void post<std::function<void ()> >(std::function<void ()>&&)::{lambda()#1}*&&)::{lambda()#1}*>()
4346+#
4347+--format=auto --no-params
4348+_Z3xxxDFyuVb
4349+xxx(unsigned long long _Fract, bool volatile)
4350+xxx
43464351 # https://sourceware.org/bugzilla/show_bug.cgi?id=16817
43474352 --format=auto --no-params
43484353 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
43494354 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
43504355 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
4356+--format=gnu-v3
4357+_Z1fSsB3fooS_
4358+f(std::string[abi:foo], std::string[abi:foo])
--- /dev/null
+++ b/libiberty/testsuite/demangler-fuzzer.c
@@ -0,0 +1,108 @@
1+/* Demangler fuzzer.
2+
3+ Copyright (C) 2014 Free Software Foundation, Inc.
4+
5+ This file is part of GNU libiberty.
6+
7+ This program is free software; you can redistribute it and/or modify
8+ it under the terms of the GNU General Public License as published by
9+ the Free Software Foundation; either version 3 of the License, or
10+ (at your option) any later version.
11+
12+ This program is distributed in the hope that it will be useful,
13+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ GNU General Public License for more details.
16+
17+ You should have received a copy of the GNU General Public License
18+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
19+
20+#include <stdio.h>
21+#include <stdlib.h>
22+#include <unistd.h>
23+#include <time.h>
24+#include "demangle.h"
25+
26+#define MAXLEN 253
27+#define ALPMIN 33
28+#define ALPMAX 127
29+
30+static char *program_name;
31+
32+#define DEFAULT_MAXCOUNT 7500000
33+
34+static void
35+print_usage (FILE *fp, int exit_value)
36+{
37+ fprintf (fp, "Usage: %s [OPTION]...\n", program_name);
38+ fprintf (fp, "Options:\n");
39+ fprintf (fp, " -h Display this message.\n");
40+ fprintf (fp, " -s SEED Select the random seed to be used.\n");
41+ fprintf (fp, " The default is to base one on the");
42+ fprintf (fp, " current time.\n");
43+ fprintf (fp, " -m MAXCOUNT Exit after MAXCOUNT symbols.\n");
44+ fprintf (fp, " The default is %d.", DEFAULT_MAXCOUNT);
45+ fprintf (fp, " Set to `-1' for no limit.\n");
46+
47+ exit (exit_value);
48+}
49+
50+int
51+main (int argc, char *argv[])
52+{
53+ char symbol[2 + MAXLEN + 1] = "_Z";
54+ int seed = -1, seed_set = 0;
55+ int count = 0, maxcount = DEFAULT_MAXCOUNT;
56+ int optchr;
57+
58+ program_name = argv[0];
59+
60+ do
61+ {
62+ optchr = getopt (argc, argv, "hs:m:t:");
63+ switch (optchr)
64+ {
65+ case '?': /* Unrecognized option. */
66+ print_usage (stderr, 1);
67+ break;
68+
69+ case 'h':
70+ print_usage (stdout, 0);
71+ break;
72+
73+ case 's':
74+ seed = atoi (optarg);
75+ seed_set = 1;
76+ break;
77+
78+ case 'm':
79+ maxcount = atoi (optarg);
80+ break;
81+ }
82+ }
83+ while (optchr != -1);
84+
85+ if (!seed_set)
86+ seed = time (NULL);
87+ srand (seed);
88+ printf ("%s: seed = %d\n", program_name, seed);
89+
90+ while (maxcount < 0 || count < maxcount)
91+ {
92+ char *buffer = symbol + 2;
93+ int length, i;
94+
95+ length = rand () % MAXLEN;
96+ for (i = 0; i < length; i++)
97+ *buffer++ = (rand () % (ALPMAX - ALPMIN)) + ALPMIN;
98+
99+ *buffer++ = '\0';
100+
101+ cplus_demangle (symbol, DMGL_AUTO | DMGL_ANSI | DMGL_PARAMS);
102+
103+ count++;
104+ }
105+
106+ printf ("%s: successfully demangled %d symbols\n", program_name, count);
107+ exit (0);
108+}