d-demangle.c revision 1.6
1/* Demangler for the D programming language
2   Copyright (C) 2014-2022 Free Software Foundation, Inc.
3   Written by Iain Buclaw (ibuclaw@gdcproject.org)
4
5This file is part of the libiberty library.
6Libiberty is free software; you can redistribute it and/or
7modify it under the terms of the GNU Library General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11In addition to the permissions in the GNU Library General Public
12License, the Free Software Foundation gives you unlimited permission
13to link the compiled version of this file into combinations with other
14programs, and to distribute those combinations without any restriction
15coming from the use of this file.  (The Library Public License
16restrictions do apply in other respects; for example, they cover
17modification of the file, and distribution when not linked into a
18combined executable.)
19
20Libiberty is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23Library General Public License for more details.
24
25You should have received a copy of the GNU Library General Public
26License along with libiberty; see the file COPYING.LIB.
27If not, see <http://www.gnu.org/licenses/>.  */
28
29/* This file exports one function; dlang_demangle.  */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34#ifdef HAVE_LIMITS_H
35#include <limits.h>
36#endif
37
38#include "safe-ctype.h"
39
40#include <sys/types.h>
41#include <string.h>
42#include <stdio.h>
43
44#ifdef HAVE_STDLIB_H
45#include <stdlib.h>
46#endif
47
48#include <demangle.h>
49#include "libiberty.h"
50
51#ifndef ULONG_MAX
52#define	ULONG_MAX	(~0UL)
53#endif
54#ifndef UINT_MAX
55#define	UINT_MAX	(~0U)
56#endif
57
58/* A mini string-handling package */
59
60typedef struct string		/* Beware: these aren't required to be */
61{				/*  '\0' terminated.  */
62  char *b;			/* pointer to start of string */
63  char *p;			/* pointer after last character */
64  char *e;			/* pointer after end of allocated space */
65} string;
66
67static void
68string_need (string *s, size_t n)
69{
70  size_t tem;
71
72  if (s->b == NULL)
73    {
74      if (n < 32)
75	{
76	  n = 32;
77	}
78      s->p = s->b = XNEWVEC (char, n);
79      s->e = s->b + n;
80    }
81  else if ((size_t) (s->e - s->p) < n)
82    {
83      tem = s->p - s->b;
84      n += tem;
85      n *= 2;
86      s->b = XRESIZEVEC (char, s->b, n);
87      s->p = s->b + tem;
88      s->e = s->b + n;
89    }
90}
91
92static void
93string_delete (string *s)
94{
95  if (s->b != NULL)
96    {
97      XDELETEVEC (s->b);
98      s->b = s->e = s->p = NULL;
99    }
100}
101
102static void
103string_init (string *s)
104{
105  s->b = s->p = s->e = NULL;
106}
107
108static int
109string_length (string *s)
110{
111  if (s->p == s->b)
112    {
113      return 0;
114    }
115  return s->p - s->b;
116}
117
118static void
119string_setlength (string *s, int n)
120{
121  if (n - string_length (s) < 0)
122    {
123      s->p = s->b + n;
124    }
125}
126
127static void
128string_append (string *p, const char *s)
129{
130  size_t n = strlen (s);
131  string_need (p, n);
132  memcpy (p->p, s, n);
133  p->p += n;
134}
135
136static void
137string_appendn (string *p, const char *s, size_t n)
138{
139  if (n != 0)
140    {
141      string_need (p, n);
142      memcpy (p->p, s, n);
143      p->p += n;
144    }
145}
146
147static void
148string_prependn (string *p, const char *s, size_t n)
149{
150  char *q;
151
152  if (n != 0)
153    {
154      string_need (p, n);
155      for (q = p->p - 1; q >= p->b; q--)
156	{
157	  q[n] = q[0];
158	}
159      memcpy (p->b, s, n);
160      p->p += n;
161    }
162}
163
164static void
165string_prepend (string *p, const char *s)
166{
167  if (s != NULL && *s != '\0')
168    {
169      string_prependn (p, s, strlen (s));
170    }
171}
172
173/* Demangle information structure we pass around.  */
174struct dlang_info
175{
176  /* The string we are demangling.  */
177  const char *s;
178  /* The index of the last back reference.  */
179  int last_backref;
180};
181
182/* Pass as the LEN to dlang_parse_template if symbol length is not known.  */
183#define TEMPLATE_LENGTH_UNKNOWN (-1UL)
184
185/* Prototypes for forward referenced functions */
186static const char *dlang_function_type (string *, const char *,
187					struct dlang_info *);
188
189static const char *dlang_function_args (string *, const char *,
190					struct dlang_info *);
191
192static const char *dlang_type (string *, const char *, struct dlang_info *);
193
194static const char *dlang_value (string *, const char *, const char *, char,
195				struct dlang_info *);
196
197static const char *dlang_parse_qualified (string *, const char *,
198					  struct dlang_info *, int);
199
200static const char *dlang_parse_mangle (string *, const char *,
201				       struct dlang_info *);
202
203static const char *dlang_parse_tuple (string *, const char *,
204				      struct dlang_info *);
205
206static const char *dlang_parse_template (string *, const char *,
207					 struct dlang_info *, unsigned long);
208
209static const char *dlang_lname (string *, const char *, unsigned long);
210
211
212/* Extract the number from MANGLED, and assign the result to RET.
213   Return the remaining string on success or NULL on failure.
214   A result larger than UINT_MAX is considered a failure.  */
215static const char *
216dlang_number (const char *mangled, unsigned long *ret)
217{
218  /* Return NULL if trying to extract something that isn't a digit.  */
219  if (mangled == NULL || !ISDIGIT (*mangled))
220    return NULL;
221
222  unsigned long val = 0;
223
224  while (ISDIGIT (*mangled))
225    {
226      unsigned long digit = mangled[0] - '0';
227
228      /* Check for overflow.  */
229      if (val > (UINT_MAX - digit) / 10)
230	return NULL;
231
232      val = val * 10 + digit;
233      mangled++;
234    }
235
236  if (*mangled == '\0')
237    return NULL;
238
239  *ret = val;
240  return mangled;
241}
242
243/* Extract the hex-digit from MANGLED, and assign the result to RET.
244   Return the remaining string on success or NULL on failure.  */
245static const char *
246dlang_hexdigit (const char *mangled, char *ret)
247{
248  char c;
249
250  /* Return NULL if trying to extract something that isn't a hexdigit.  */
251  if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1]))
252    return NULL;
253
254  c = mangled[0];
255  if (!ISDIGIT (c))
256    *ret = c - (ISUPPER (c) ? 'A' : 'a') + 10;
257  else
258    *ret = c - '0';
259
260  c = mangled[1];
261  if (!ISDIGIT (c))
262    *ret = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10);
263  else
264    *ret = (*ret << 4) | (c - '0');
265
266  mangled += 2;
267
268  return mangled;
269}
270
271/* Extract the function calling convention from MANGLED and
272   return 1 on success or 0 on failure.  */
273static int
274dlang_call_convention_p (const char *mangled)
275{
276  switch (*mangled)
277    {
278    case 'F': case 'U': case 'V':
279    case 'W': case 'R': case 'Y':
280      return 1;
281
282    default:
283      return 0;
284    }
285}
286
287/* Extract the back reference position from MANGLED, and assign the result
288   to RET.  Return the remaining string on success or NULL on failure.
289   A result <= 0 is a failure.  */
290static const char *
291dlang_decode_backref (const char *mangled, long *ret)
292{
293  /* Return NULL if trying to extract something that isn't a digit.  */
294  if (mangled == NULL || !ISALPHA (*mangled))
295    return NULL;
296
297  /* Any identifier or non-basic type that has been emitted to the mangled
298     symbol before will not be emitted again, but is referenced by a special
299     sequence encoding the relative position of the original occurrence in the
300     mangled symbol name.
301
302     Numbers in back references are encoded with base 26 by upper case letters
303     A-Z for higher digits but lower case letters a-z for the last digit.
304
305	NumberBackRef:
306	    [a-z]
307	    [A-Z] NumberBackRef
308	    ^
309   */
310  unsigned long val = 0;
311
312  while (ISALPHA (*mangled))
313    {
314      /* Check for overflow.  */
315      if (val > (ULONG_MAX - 25) / 26)
316	break;
317
318      val *= 26;
319
320      if (mangled[0] >= 'a' && mangled[0] <= 'z')
321	{
322	  val += mangled[0] - 'a';
323	  if ((long) val <= 0)
324	    break;
325	  *ret = val;
326	  return mangled + 1;
327	}
328
329      val += mangled[0] - 'A';
330      mangled++;
331    }
332
333  return NULL;
334}
335
336/* Extract the symbol pointed at by the back reference and assign the result
337   to RET.  Return the remaining string on success or NULL on failure.  */
338static const char *
339dlang_backref (const char *mangled, const char **ret, struct dlang_info *info)
340{
341  *ret = NULL;
342
343  if (mangled == NULL || *mangled != 'Q')
344    return NULL;
345
346  /* Position of 'Q'.  */
347  const char *qpos = mangled;
348  long refpos;
349  mangled++;
350
351  mangled = dlang_decode_backref (mangled, &refpos);
352  if (mangled == NULL)
353    return NULL;
354
355  if (refpos > qpos - info->s)
356    return NULL;
357
358  /* Set the position of the back reference.  */
359  *ret = qpos - refpos;
360
361  return mangled;
362}
363
364/* Demangle a back referenced symbol from MANGLED and append it to DECL.
365   Return the remaining string on success or NULL on failure.  */
366static const char *
367dlang_symbol_backref (string *decl, const char *mangled,
368		      struct dlang_info *info)
369{
370  /* An identifier back reference always points to a digit 0 to 9.
371
372	IdentifierBackRef:
373	    Q NumberBackRef
374	    ^
375   */
376  const char *backref;
377  unsigned long len;
378
379  /* Get position of the back reference.  */
380  mangled = dlang_backref (mangled, &backref, info);
381
382  /* Must point to a simple identifier.  */
383  backref = dlang_number (backref, &len);
384  if (backref == NULL || strlen(backref) < len)
385    return NULL;
386
387  backref = dlang_lname (decl, backref, len);
388  if (backref == NULL)
389    return NULL;
390
391  return mangled;
392}
393
394/* Demangle a back referenced type from MANGLED and append it to DECL.
395   IS_FUNCTION is 1 if the back referenced type is expected to be a function.
396   Return the remaining string on success or NULL on failure.  */
397static const char *
398dlang_type_backref (string *decl, const char *mangled, struct dlang_info *info,
399		    int is_function)
400{
401  /* A type back reference always points to a letter.
402
403	TypeBackRef:
404	    Q NumberBackRef
405	    ^
406   */
407  const char *backref;
408
409  /* If we appear to be moving backwards through the mangle string, then
410     bail as this may be a recursive back reference.  */
411  if (mangled - info->s >= info->last_backref)
412    return NULL;
413
414  int save_refpos = info->last_backref;
415  info->last_backref = mangled - info->s;
416
417  /* Get position of the back reference.  */
418  mangled = dlang_backref (mangled, &backref, info);
419
420  /* Must point to a type.  */
421  if (is_function)
422    backref = dlang_function_type (decl, backref, info);
423  else
424    backref = dlang_type (decl, backref, info);
425
426  info->last_backref = save_refpos;
427
428  if (backref == NULL)
429    return NULL;
430
431  return mangled;
432}
433
434/* Extract the beginning of a symbol name from MANGLED and
435   return 1 on success or 0 on failure.  */
436static int
437dlang_symbol_name_p (const char *mangled, struct dlang_info *info)
438{
439  long ret;
440  const char *qref = mangled;
441
442  if (ISDIGIT (*mangled))
443    return 1;
444
445  if (mangled[0] == '_' && mangled[1] == '_'
446      && (mangled[2] == 'T' || mangled[2] == 'U'))
447    return 1;
448
449  if (*mangled != 'Q')
450    return 0;
451
452  mangled = dlang_decode_backref (mangled + 1, &ret);
453  if (mangled == NULL || ret > qref - info->s)
454    return 0;
455
456  return ISDIGIT (qref[-ret]);
457}
458
459/* Demangle the calling convention from MANGLED and append it to DECL.
460   Return the remaining string on success or NULL on failure.  */
461static const char *
462dlang_call_convention (string *decl, const char *mangled)
463{
464  if (mangled == NULL || *mangled == '\0')
465    return NULL;
466
467  switch (*mangled)
468    {
469    case 'F': /* (D) */
470      mangled++;
471      break;
472    case 'U': /* (C) */
473      mangled++;
474      string_append (decl, "extern(C) ");
475      break;
476    case 'W': /* (Windows) */
477      mangled++;
478      string_append (decl, "extern(Windows) ");
479      break;
480    case 'V': /* (Pascal) */
481      mangled++;
482      string_append (decl, "extern(Pascal) ");
483      break;
484    case 'R': /* (C++) */
485      mangled++;
486      string_append (decl, "extern(C++) ");
487      break;
488    case 'Y': /* (Objective-C) */
489      mangled++;
490      string_append (decl, "extern(Objective-C) ");
491      break;
492    default:
493      return NULL;
494    }
495
496  return mangled;
497}
498
499/* Extract the type modifiers from MANGLED and append them to DECL.
500   Returns the remaining signature on success or NULL on failure.  */
501static const char *
502dlang_type_modifiers (string *decl, const char *mangled)
503{
504  if (mangled == NULL || *mangled == '\0')
505    return NULL;
506
507  switch (*mangled)
508    {
509    case 'x': /* const */
510      mangled++;
511      string_append (decl, " const");
512      return mangled;
513    case 'y': /* immutable */
514      mangled++;
515      string_append (decl, " immutable");
516      return mangled;
517    case 'O': /* shared */
518      mangled++;
519      string_append (decl, " shared");
520      return dlang_type_modifiers (decl, mangled);
521    case 'N':
522      mangled++;
523      if (*mangled == 'g') /* wild */
524	{
525	  mangled++;
526	  string_append (decl, " inout");
527	  return dlang_type_modifiers (decl, mangled);
528	}
529      else
530	return NULL;
531
532    default:
533      return mangled;
534    }
535}
536
537/* Demangle the D function attributes from MANGLED and append it to DECL.
538   Return the remaining string on success or NULL on failure.  */
539static const char *
540dlang_attributes (string *decl, const char *mangled)
541{
542  if (mangled == NULL || *mangled == '\0')
543    return NULL;
544
545  while (*mangled == 'N')
546    {
547      mangled++;
548      switch (*mangled)
549	{
550	case 'a': /* pure */
551	  mangled++;
552	  string_append (decl, "pure ");
553	  continue;
554	case 'b': /* nothrow */
555	  mangled++;
556	  string_append (decl, "nothrow ");
557	  continue;
558	case 'c': /* ref */
559	  mangled++;
560	  string_append (decl, "ref ");
561	  continue;
562	case 'd': /* @property */
563	  mangled++;
564	  string_append (decl, "@property ");
565	  continue;
566	case 'e': /* @trusted */
567	  mangled++;
568	  string_append (decl, "@trusted ");
569	  continue;
570	case 'f': /* @safe */
571	  mangled++;
572	  string_append (decl, "@safe ");
573	  continue;
574	case 'g':
575	case 'h':
576	case 'k':
577	case 'n':
578	  /* inout parameter is represented as 'Ng'.
579	     vector parameter is represented as 'Nh'.
580	     return parameter is represented as 'Nk'.
581	     typeof(*null) parameter is represented as 'Nn'.
582	     If we see this, then we know we're really in the
583	     parameter list.  Rewind and break.  */
584	  mangled--;
585	  break;
586	case 'i': /* @nogc */
587	  mangled++;
588	  string_append (decl, "@nogc ");
589	  continue;
590	case 'j': /* return */
591	  mangled++;
592	  string_append (decl, "return ");
593	  continue;
594	case 'l': /* scope */
595	  mangled++;
596	  string_append (decl, "scope ");
597	  continue;
598	case 'm': /* @live */
599	  mangled++;
600	  string_append (decl, "@live ");
601	  continue;
602
603	default: /* unknown attribute */
604	  return NULL;
605	}
606      break;
607    }
608
609  return mangled;
610}
611
612/* Demangle the function type from MANGLED without the return type.
613   The arguments are appended to ARGS, the calling convention is appended
614   to CALL and attributes are appended to ATTR.  Any of these can be NULL
615   to throw the information away.  Return the remaining string on success
616   or NULL on failure.  */
617static const char *
618dlang_function_type_noreturn (string *args, string *call, string *attr,
619			      const char *mangled, struct dlang_info *info)
620{
621  string dump;
622  string_init (&dump);
623
624  /* Skip over calling convention and attributes.  */
625  mangled = dlang_call_convention (call ? call : &dump, mangled);
626  mangled = dlang_attributes (attr ? attr : &dump, mangled);
627
628  if (args)
629    string_append (args, "(");
630
631  mangled = dlang_function_args (args ? args : &dump, mangled, info);
632  if (args)
633    string_append (args, ")");
634
635  string_delete (&dump);
636  return mangled;
637}
638
639/* Demangle the function type from MANGLED and append it to DECL.
640   Return the remaining string on success or NULL on failure.  */
641static const char *
642dlang_function_type (string *decl, const char *mangled, struct dlang_info *info)
643{
644  string attr, args, type;
645
646  if (mangled == NULL || *mangled == '\0')
647    return NULL;
648
649  /* The order of the mangled string is:
650	CallConvention FuncAttrs Arguments ArgClose Type
651
652     The demangled string is re-ordered as:
653	CallConvention Type Arguments FuncAttrs
654   */
655  string_init (&attr);
656  string_init (&args);
657  string_init (&type);
658
659  mangled = dlang_function_type_noreturn (&args, decl, &attr, mangled, info);
660
661  /* Function return type.  */
662  mangled = dlang_type (&type, mangled, info);
663
664  /* Append to decl in order. */
665  string_appendn (decl, type.b, string_length (&type));
666  string_appendn (decl, args.b, string_length (&args));
667  string_append (decl, " ");
668  string_appendn (decl, attr.b, string_length (&attr));
669
670  string_delete (&attr);
671  string_delete (&args);
672  string_delete (&type);
673  return mangled;
674}
675
676/* Demangle the argument list from MANGLED and append it to DECL.
677   Return the remaining string on success or NULL on failure.  */
678static const char *
679dlang_function_args (string *decl, const char *mangled, struct dlang_info *info)
680{
681  size_t n = 0;
682
683  while (mangled && *mangled != '\0')
684    {
685      switch (*mangled)
686	{
687	case 'X': /* (variadic T t...) style.  */
688	  mangled++;
689	  string_append (decl, "...");
690	  return mangled;
691	case 'Y': /* (variadic T t, ...) style.  */
692	  mangled++;
693	  if (n != 0)
694	    string_append (decl, ", ");
695	  string_append (decl, "...");
696	  return mangled;
697	case 'Z': /* Normal function.  */
698	  mangled++;
699	  return mangled;
700	}
701
702      if (n++)
703	string_append (decl, ", ");
704
705      if (*mangled == 'M') /* scope(T) */
706	{
707	  mangled++;
708	  string_append (decl, "scope ");
709	}
710
711      if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
712	{
713	  mangled += 2;
714	  string_append (decl, "return ");
715	}
716
717      switch (*mangled)
718	{
719	case 'I': /* in(T) */
720	  mangled++;
721	  string_append (decl, "in ");
722	  if (*mangled == 'K') /* in ref(T) */
723	    {
724	      mangled++;
725	      string_append (decl, "ref ");
726	    }
727	  break;
728	case 'J': /* out(T) */
729	  mangled++;
730	  string_append (decl, "out ");
731	  break;
732	case 'K': /* ref(T) */
733	  mangled++;
734	  string_append (decl, "ref ");
735	  break;
736	case 'L': /* lazy(T) */
737	  mangled++;
738	  string_append (decl, "lazy ");
739	  break;
740	}
741      mangled = dlang_type (decl, mangled, info);
742    }
743
744  return mangled;
745}
746
747/* Demangle the type from MANGLED and append it to DECL.
748   Return the remaining string on success or NULL on failure.  */
749static const char *
750dlang_type (string *decl, const char *mangled, struct dlang_info *info)
751{
752  if (mangled == NULL || *mangled == '\0')
753    return NULL;
754
755  switch (*mangled)
756    {
757    case 'O': /* shared(T) */
758      mangled++;
759      string_append (decl, "shared(");
760      mangled = dlang_type (decl, mangled, info);
761      string_append (decl, ")");
762      return mangled;
763    case 'x': /* const(T) */
764      mangled++;
765      string_append (decl, "const(");
766      mangled = dlang_type (decl, mangled, info);
767      string_append (decl, ")");
768      return mangled;
769    case 'y': /* immutable(T) */
770      mangled++;
771      string_append (decl, "immutable(");
772      mangled = dlang_type (decl, mangled, info);
773      string_append (decl, ")");
774      return mangled;
775    case 'N':
776      mangled++;
777      if (*mangled == 'g') /* wild(T) */
778	{
779	  mangled++;
780	  string_append (decl, "inout(");
781	  mangled = dlang_type (decl, mangled, info);
782	  string_append (decl, ")");
783	  return mangled;
784	}
785      else if (*mangled == 'h') /* vector(T) */
786	{
787	  mangled++;
788	  string_append (decl, "__vector(");
789	  mangled = dlang_type (decl, mangled, info);
790	  string_append (decl, ")");
791	  return mangled;
792	}
793      else if (*mangled == 'n') /* typeof(*null) */
794	{
795	  mangled++;
796	  string_append (decl, "typeof(*null)");
797	  return mangled;
798	}
799      else
800	return NULL;
801    case 'A': /* dynamic array (T[]) */
802      mangled++;
803      mangled = dlang_type (decl, mangled, info);
804      string_append (decl, "[]");
805      return mangled;
806    case 'G': /* static array (T[N]) */
807    {
808      const char *numptr;
809      size_t num = 0;
810      mangled++;
811
812      numptr = mangled;
813      while (ISDIGIT (*mangled))
814	{
815	  num++;
816	  mangled++;
817	}
818      mangled = dlang_type (decl, mangled, info);
819      string_append (decl, "[");
820      string_appendn (decl, numptr, num);
821      string_append (decl, "]");
822      return mangled;
823    }
824    case 'H': /* associative array (T[T]) */
825    {
826      string type;
827      size_t sztype;
828      mangled++;
829
830      string_init (&type);
831      mangled = dlang_type (&type, mangled, info);
832      sztype = string_length (&type);
833
834      mangled = dlang_type (decl, mangled, info);
835      string_append (decl, "[");
836      string_appendn (decl, type.b, sztype);
837      string_append (decl, "]");
838
839      string_delete (&type);
840      return mangled;
841    }
842    case 'P': /* pointer (T*) */
843      mangled++;
844      if (!dlang_call_convention_p (mangled))
845	{
846	  mangled = dlang_type (decl, mangled, info);
847	  string_append (decl, "*");
848	  return mangled;
849	}
850      /* Fall through */
851    case 'F': /* function T (D) */
852    case 'U': /* function T (C) */
853    case 'W': /* function T (Windows) */
854    case 'V': /* function T (Pascal) */
855    case 'R': /* function T (C++) */
856    case 'Y': /* function T (Objective-C) */
857      /* Function pointer types don't include the trailing asterisk.  */
858      mangled = dlang_function_type (decl, mangled, info);
859      string_append (decl, "function");
860      return mangled;
861    case 'C': /* class T */
862    case 'S': /* struct T */
863    case 'E': /* enum T */
864    case 'T': /* typedef T */
865      mangled++;
866      return dlang_parse_qualified (decl, mangled, info, 0);
867    case 'D': /* delegate T */
868    {
869      string mods;
870      size_t szmods;
871      mangled++;
872
873      string_init (&mods);
874      mangled = dlang_type_modifiers (&mods, mangled);
875      szmods = string_length (&mods);
876
877      /* Back referenced function type.  */
878      if (mangled && *mangled == 'Q')
879	mangled = dlang_type_backref (decl, mangled, info, 1);
880      else
881	mangled = dlang_function_type (decl, mangled, info);
882
883      string_append (decl, "delegate");
884      string_appendn (decl, mods.b, szmods);
885
886      string_delete (&mods);
887      return mangled;
888    }
889    case 'B': /* tuple T */
890      mangled++;
891      return dlang_parse_tuple (decl, mangled, info);
892
893    /* Basic types */
894    case 'n':
895      mangled++;
896      string_append (decl, "typeof(null)");
897      return mangled;
898    case 'v':
899      mangled++;
900      string_append (decl, "void");
901      return mangled;
902    case 'g':
903      mangled++;
904      string_append (decl, "byte");
905      return mangled;
906    case 'h':
907      mangled++;
908      string_append (decl, "ubyte");
909      return mangled;
910    case 's':
911      mangled++;
912      string_append (decl, "short");
913      return mangled;
914    case 't':
915      mangled++;
916      string_append (decl, "ushort");
917      return mangled;
918    case 'i':
919      mangled++;
920      string_append (decl, "int");
921      return mangled;
922    case 'k':
923      mangled++;
924      string_append (decl, "uint");
925      return mangled;
926    case 'l':
927      mangled++;
928      string_append (decl, "long");
929      return mangled;
930    case 'm':
931      mangled++;
932      string_append (decl, "ulong");
933      return mangled;
934    case 'f':
935      mangled++;
936      string_append (decl, "float");
937      return mangled;
938    case 'd':
939      mangled++;
940      string_append (decl, "double");
941      return mangled;
942    case 'e':
943      mangled++;
944      string_append (decl, "real");
945      return mangled;
946
947    /* Imaginary and Complex types */
948    case 'o':
949      mangled++;
950      string_append (decl, "ifloat");
951      return mangled;
952    case 'p':
953      mangled++;
954      string_append (decl, "idouble");
955      return mangled;
956    case 'j':
957      mangled++;
958      string_append (decl, "ireal");
959      return mangled;
960    case 'q':
961      mangled++;
962      string_append (decl, "cfloat");
963      return mangled;
964    case 'r':
965      mangled++;
966      string_append (decl, "cdouble");
967      return mangled;
968    case 'c':
969      mangled++;
970      string_append (decl, "creal");
971      return mangled;
972
973    /* Other types */
974    case 'b':
975      mangled++;
976      string_append (decl, "bool");
977      return mangled;
978    case 'a':
979      mangled++;
980      string_append (decl, "char");
981      return mangled;
982    case 'u':
983      mangled++;
984      string_append (decl, "wchar");
985      return mangled;
986    case 'w':
987      mangled++;
988      string_append (decl, "dchar");
989      return mangled;
990    case 'z':
991      mangled++;
992      switch (*mangled)
993	{
994	case 'i':
995	  mangled++;
996	  string_append (decl, "cent");
997	  return mangled;
998	case 'k':
999	  mangled++;
1000	  string_append (decl, "ucent");
1001	  return mangled;
1002	}
1003      return NULL;
1004
1005    /* Back referenced type.  */
1006    case 'Q':
1007      return dlang_type_backref (decl, mangled, info, 0);
1008
1009    default: /* unhandled */
1010      return NULL;
1011    }
1012}
1013
1014/* Extract the identifier from MANGLED and append it to DECL.
1015   Return the remaining string on success or NULL on failure.  */
1016static const char *
1017dlang_identifier (string *decl, const char *mangled, struct dlang_info *info)
1018{
1019  unsigned long len;
1020
1021  if (mangled == NULL || *mangled == '\0')
1022    return NULL;
1023
1024  if (*mangled == 'Q')
1025    return dlang_symbol_backref (decl, mangled, info);
1026
1027  /* May be a template instance without a length prefix.  */
1028  if (mangled[0] == '_' && mangled[1] == '_'
1029      && (mangled[2] == 'T' || mangled[2] == 'U'))
1030    return dlang_parse_template (decl, mangled, info, TEMPLATE_LENGTH_UNKNOWN);
1031
1032  const char *endptr = dlang_number (mangled, &len);
1033
1034  if (endptr == NULL || len == 0)
1035    return NULL;
1036
1037  if (strlen (endptr) < len)
1038    return NULL;
1039
1040  mangled = endptr;
1041
1042  /* May be a template instance with a length prefix.  */
1043  if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
1044      && (mangled[2] == 'T' || mangled[2] == 'U'))
1045    return dlang_parse_template (decl, mangled, info, len);
1046
1047  /* There can be multiple different declarations in the same function that have
1048     the same mangled name.  To make the mangled names unique, a fake parent in
1049     the form `__Sddd' is added to the symbol.  */
1050  if (len >= 4 && mangled[0] == '_' && mangled[1] == '_' && mangled[2] == 'S')
1051    {
1052      const char *numptr = mangled + 3;
1053      while (numptr < (mangled + len) && ISDIGIT (*numptr))
1054	numptr++;
1055
1056      if (mangled + len == numptr)
1057	{
1058	  /* Skip over the fake parent.  */
1059	  mangled += len;
1060	  return dlang_identifier (decl, mangled, info);
1061	}
1062
1063      /* else demangle it as a plain identifier.  */
1064    }
1065
1066  return dlang_lname (decl, mangled, len);
1067}
1068
1069/* Extract the plain identifier from MANGLED and prepend/append it to DECL
1070   with special treatment for some magic compiler generted symbols.
1071   Return the remaining string on success or NULL on failure.  */
1072static const char *
1073dlang_lname (string *decl, const char *mangled, unsigned long len)
1074{
1075  switch (len)
1076    {
1077    case 6:
1078      if (strncmp (mangled, "__ctor", len) == 0)
1079	{
1080	  /* Constructor symbol for a class/struct.  */
1081	  string_append (decl, "this");
1082	  mangled += len;
1083	  return mangled;
1084	}
1085      else if (strncmp (mangled, "__dtor", len) == 0)
1086	{
1087	  /* Destructor symbol for a class/struct.  */
1088	  string_append (decl, "~this");
1089	  mangled += len;
1090	  return mangled;
1091	}
1092      else if (strncmp (mangled, "__initZ", len + 1) == 0)
1093	{
1094	  /* The static initialiser for a given symbol.  */
1095	  string_prepend (decl, "initializer for ");
1096	  string_setlength (decl, string_length (decl) - 1);
1097	  mangled += len;
1098	  return mangled;
1099	}
1100      else if (strncmp (mangled, "__vtblZ", len + 1) == 0)
1101	{
1102	  /* The vtable symbol for a given class.  */
1103	  string_prepend (decl, "vtable for ");
1104	  string_setlength (decl, string_length (decl) - 1);
1105	  mangled += len;
1106	  return mangled;
1107	}
1108      break;
1109
1110    case 7:
1111      if (strncmp (mangled, "__ClassZ", len + 1) == 0)
1112	{
1113	  /* The classinfo symbol for a given class.  */
1114	  string_prepend (decl, "ClassInfo for ");
1115	  string_setlength (decl, string_length (decl) - 1);
1116	  mangled += len;
1117	  return mangled;
1118	}
1119      break;
1120
1121    case 10:
1122      if (strncmp (mangled, "__postblitMFZ", len + 3) == 0)
1123	{
1124	  /* Postblit symbol for a struct.  */
1125	  string_append (decl, "this(this)");
1126	  mangled += len + 3;
1127	  return mangled;
1128	}
1129      break;
1130
1131    case 11:
1132      if (strncmp (mangled, "__InterfaceZ", len + 1) == 0)
1133	{
1134	  /* The interface symbol for a given class.  */
1135	  string_prepend (decl, "Interface for ");
1136	  string_setlength (decl, string_length (decl) - 1);
1137	  mangled += len;
1138	  return mangled;
1139	}
1140      break;
1141
1142    case 12:
1143      if (strncmp (mangled, "__ModuleInfoZ", len + 1) == 0)
1144	{
1145	  /* The ModuleInfo symbol for a given module.  */
1146	  string_prepend (decl, "ModuleInfo for ");
1147	  string_setlength (decl, string_length (decl) - 1);
1148	  mangled += len;
1149	  return mangled;
1150	}
1151      break;
1152    }
1153
1154  string_appendn (decl, mangled, len);
1155  mangled += len;
1156
1157  return mangled;
1158}
1159
1160/* Extract the integer value from MANGLED and append it to DECL,
1161   where TYPE is the type it should be represented as.
1162   Return the remaining string on success or NULL on failure.  */
1163static const char *
1164dlang_parse_integer (string *decl, const char *mangled, char type)
1165{
1166  if (type == 'a' || type == 'u' || type == 'w')
1167    {
1168      /* Parse character value.  */
1169      char value[20];
1170      int pos = sizeof(value);
1171      int width = 0;
1172      unsigned long val;
1173
1174      mangled = dlang_number (mangled, &val);
1175      if (mangled == NULL)
1176	return NULL;
1177
1178      string_append (decl, "'");
1179
1180      if (type == 'a' && val >= 0x20 && val < 0x7F)
1181	{
1182	  /* Represent as a character literal.  */
1183	  char c = (char) val;
1184	  string_appendn (decl, &c, 1);
1185	}
1186      else
1187	{
1188	  /* Represent as a hexadecimal value.  */
1189	  switch (type)
1190	    {
1191	    case 'a': /* char */
1192	      string_append (decl, "\\x");
1193	      width = 2;
1194	      break;
1195	    case 'u': /* wchar */
1196	      string_append (decl, "\\u");
1197	      width = 4;
1198	      break;
1199	    case 'w': /* dchar */
1200	      string_append (decl, "\\U");
1201	      width = 8;
1202	      break;
1203	    }
1204
1205	  while (val > 0)
1206	    {
1207	      int digit = val % 16;
1208
1209	      if (digit < 10)
1210		value[--pos] = (char)(digit + '0');
1211	      else
1212		value[--pos] = (char)((digit - 10) + 'a');
1213
1214	      val /= 16;
1215	      width--;
1216	    }
1217
1218	  for (; width > 0; width--)
1219	    value[--pos] = '0';
1220
1221	  string_appendn (decl, &(value[pos]), sizeof(value) - pos);
1222	}
1223      string_append (decl, "'");
1224    }
1225  else if (type == 'b')
1226    {
1227      /* Parse boolean value.  */
1228      unsigned long val;
1229
1230      mangled = dlang_number (mangled, &val);
1231      if (mangled == NULL)
1232	return NULL;
1233
1234      string_append (decl, val ? "true" : "false");
1235    }
1236  else
1237    {
1238      /* Parse integer value.  */
1239      const char *numptr = mangled;
1240      size_t num = 0;
1241
1242      if (! ISDIGIT (*mangled))
1243	return NULL;
1244
1245      while (ISDIGIT (*mangled))
1246	{
1247	  num++;
1248	  mangled++;
1249	}
1250      string_appendn (decl, numptr, num);
1251
1252      /* Append suffix.  */
1253      switch (type)
1254	{
1255	case 'h': /* ubyte */
1256	case 't': /* ushort */
1257	case 'k': /* uint */
1258	  string_append (decl, "u");
1259	  break;
1260	case 'l': /* long */
1261	  string_append (decl, "L");
1262	  break;
1263	case 'm': /* ulong */
1264	  string_append (decl, "uL");
1265	  break;
1266	}
1267    }
1268
1269  return mangled;
1270}
1271
1272/* Extract the floating-point value from MANGLED and append it to DECL.
1273   Return the remaining string on success or NULL on failure.  */
1274static const char *
1275dlang_parse_real (string *decl, const char *mangled)
1276{
1277  /* Handle NAN and +-INF.  */
1278  if (strncmp (mangled, "NAN", 3) == 0)
1279    {
1280      string_append (decl, "NaN");
1281      mangled += 3;
1282      return mangled;
1283    }
1284  else if (strncmp (mangled, "INF", 3) == 0)
1285    {
1286      string_append (decl, "Inf");
1287      mangled += 3;
1288      return mangled;
1289    }
1290  else if (strncmp (mangled, "NINF", 4) == 0)
1291    {
1292      string_append (decl, "-Inf");
1293      mangled += 4;
1294      return mangled;
1295    }
1296
1297  /* Hexadecimal prefix and leading bit.  */
1298  if (*mangled == 'N')
1299    {
1300      string_append (decl, "-");
1301      mangled++;
1302    }
1303
1304  if (!ISXDIGIT (*mangled))
1305    return NULL;
1306
1307  string_append (decl, "0x");
1308  string_appendn (decl, mangled, 1);
1309  string_append (decl, ".");
1310  mangled++;
1311
1312  /* Significand.  */
1313  while (ISXDIGIT (*mangled))
1314    {
1315      string_appendn (decl, mangled, 1);
1316      mangled++;
1317    }
1318
1319  /* Exponent.  */
1320  if (*mangled != 'P')
1321    return NULL;
1322
1323  string_append (decl, "p");
1324  mangled++;
1325
1326  if (*mangled == 'N')
1327    {
1328      string_append (decl, "-");
1329      mangled++;
1330    }
1331
1332  while (ISDIGIT (*mangled))
1333    {
1334      string_appendn (decl, mangled, 1);
1335      mangled++;
1336    }
1337
1338  return mangled;
1339}
1340
1341/* Extract the string value from MANGLED and append it to DECL.
1342   Return the remaining string on success or NULL on failure.  */
1343static const char *
1344dlang_parse_string (string *decl, const char *mangled)
1345{
1346  char type = *mangled;
1347  unsigned long len;
1348
1349  mangled++;
1350  mangled = dlang_number (mangled, &len);
1351  if (mangled == NULL || *mangled != '_')
1352    return NULL;
1353
1354  mangled++;
1355  string_append (decl, "\"");
1356  while (len--)
1357    {
1358      char val;
1359      const char *endptr = dlang_hexdigit (mangled, &val);
1360
1361      if (endptr == NULL)
1362	return NULL;
1363
1364      /* Sanitize white and non-printable characters.  */
1365      switch (val)
1366	{
1367	case ' ':
1368	  string_append (decl, " ");
1369	  break;
1370	case '\t':
1371	  string_append (decl, "\\t");
1372	  break;
1373	case '\n':
1374	  string_append (decl, "\\n");
1375	  break;
1376	case '\r':
1377	  string_append (decl, "\\r");
1378	  break;
1379	case '\f':
1380	  string_append (decl, "\\f");
1381	  break;
1382	case '\v':
1383	  string_append (decl, "\\v");
1384	  break;
1385
1386	default:
1387	  if (ISPRINT (val))
1388	    string_appendn (decl, &val, 1);
1389	  else
1390	    {
1391	      string_append (decl, "\\x");
1392	      string_appendn (decl, mangled, 2);
1393	    }
1394	}
1395
1396      mangled = endptr;
1397    }
1398  string_append (decl, "\"");
1399
1400  if (type != 'a')
1401    string_appendn (decl, &type, 1);
1402
1403  return mangled;
1404}
1405
1406/* Extract the static array value from MANGLED and append it to DECL.
1407   Return the remaining string on success or NULL on failure.  */
1408static const char *
1409dlang_parse_arrayliteral (string *decl, const char *mangled,
1410			  struct dlang_info *info)
1411{
1412  unsigned long elements;
1413
1414  mangled = dlang_number (mangled, &elements);
1415  if (mangled == NULL)
1416    return NULL;
1417
1418  string_append (decl, "[");
1419  while (elements--)
1420    {
1421      mangled = dlang_value (decl, mangled, NULL, '\0', info);
1422      if (mangled == NULL)
1423	return NULL;
1424
1425      if (elements != 0)
1426	string_append (decl, ", ");
1427    }
1428
1429  string_append (decl, "]");
1430  return mangled;
1431}
1432
1433/* Extract the associative array value from MANGLED and append it to DECL.
1434   Return the remaining string on success or NULL on failure.  */
1435static const char *
1436dlang_parse_assocarray (string *decl, const char *mangled,
1437			struct dlang_info *info)
1438{
1439  unsigned long elements;
1440
1441  mangled = dlang_number (mangled, &elements);
1442  if (mangled == NULL)
1443    return NULL;
1444
1445  string_append (decl, "[");
1446  while (elements--)
1447    {
1448      mangled = dlang_value (decl, mangled, NULL, '\0', info);
1449      if (mangled == NULL)
1450	return NULL;
1451
1452      string_append (decl, ":");
1453      mangled = dlang_value (decl, mangled, NULL, '\0', info);
1454      if (mangled == NULL)
1455	return NULL;
1456
1457      if (elements != 0)
1458	string_append (decl, ", ");
1459    }
1460
1461  string_append (decl, "]");
1462  return mangled;
1463}
1464
1465/* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1466   Return the remaining string on success or NULL on failure.  */
1467static const char *
1468dlang_parse_structlit (string *decl, const char *mangled, const char *name,
1469		       struct dlang_info *info)
1470{
1471  unsigned long args;
1472
1473  mangled = dlang_number (mangled, &args);
1474  if (mangled == NULL)
1475    return NULL;
1476
1477  if (name != NULL)
1478    string_append (decl, name);
1479
1480  string_append (decl, "(");
1481  while (args--)
1482    {
1483      mangled = dlang_value (decl, mangled, NULL, '\0', info);
1484      if (mangled == NULL)
1485	return NULL;
1486
1487      if (args != 0)
1488	string_append (decl, ", ");
1489    }
1490
1491  string_append (decl, ")");
1492  return mangled;
1493}
1494
1495/* Extract the value from MANGLED and append it to DECL.
1496   Return the remaining string on success or NULL on failure.  */
1497static const char *
1498dlang_value (string *decl, const char *mangled, const char *name, char type,
1499	     struct dlang_info *info)
1500{
1501  if (mangled == NULL || *mangled == '\0')
1502    return NULL;
1503
1504  switch (*mangled)
1505    {
1506      /* Null value.  */
1507    case 'n':
1508      mangled++;
1509      string_append (decl, "null");
1510      break;
1511
1512      /* Integral values.  */
1513    case 'N':
1514      mangled++;
1515      string_append (decl, "-");
1516      mangled = dlang_parse_integer (decl, mangled, type);
1517      break;
1518
1519    case 'i':
1520      mangled++;
1521      /* Fall through */
1522
1523      /* There really should always be an `i' before encoded numbers, but there
1524	 wasn't in early versions of D2, so this case range must remain for
1525	 backwards compatibility.  */
1526    case '0': case '1': case '2': case '3': case '4':
1527    case '5': case '6': case '7': case '8': case '9':
1528      mangled = dlang_parse_integer (decl, mangled, type);
1529      break;
1530
1531      /* Real value.  */
1532    case 'e':
1533      mangled++;
1534      mangled = dlang_parse_real (decl, mangled);
1535      break;
1536
1537      /* Complex value.  */
1538    case 'c':
1539      mangled++;
1540      mangled = dlang_parse_real (decl, mangled);
1541      string_append (decl, "+");
1542      if (mangled == NULL || *mangled != 'c')
1543	return NULL;
1544      mangled++;
1545      mangled = dlang_parse_real (decl, mangled);
1546      string_append (decl, "i");
1547      break;
1548
1549      /* String values.  */
1550    case 'a': /* UTF8 */
1551    case 'w': /* UTF16 */
1552    case 'd': /* UTF32 */
1553      mangled = dlang_parse_string (decl, mangled);
1554      break;
1555
1556      /* Array values.  */
1557    case 'A':
1558      mangled++;
1559      if (type == 'H')
1560	mangled = dlang_parse_assocarray (decl, mangled, info);
1561      else
1562	mangled = dlang_parse_arrayliteral (decl, mangled, info);
1563      break;
1564
1565      /* Struct values.  */
1566    case 'S':
1567      mangled++;
1568      mangled = dlang_parse_structlit (decl, mangled, name, info);
1569      break;
1570
1571      /* Function literal symbol.  */
1572    case 'f':
1573      mangled++;
1574      if (strncmp (mangled, "_D", 2) != 0
1575	  || !dlang_symbol_name_p (mangled + 2, info))
1576	return NULL;
1577      mangled = dlang_parse_mangle (decl, mangled, info);
1578      break;
1579
1580    default:
1581      return NULL;
1582    }
1583
1584  return mangled;
1585}
1586
1587/* Extract and demangle the symbol in MANGLED and append it to DECL.
1588   Returns the remaining signature on success or NULL on failure.  */
1589static const char *
1590dlang_parse_mangle (string *decl, const char *mangled, struct dlang_info *info)
1591{
1592  /* A D mangled symbol is comprised of both scope and type information.
1593
1594	MangleName:
1595	    _D QualifiedName Type
1596	    _D QualifiedName Z
1597	    ^
1598     The caller should have guaranteed that the start pointer is at the
1599     above location.
1600     Note that type is never a function type, but only the return type of
1601     a function or the type of a variable.
1602   */
1603  mangled += 2;
1604
1605  mangled = dlang_parse_qualified (decl, mangled, info, 1);
1606
1607  if (mangled != NULL)
1608    {
1609      /* Artificial symbols end with 'Z' and have no type.  */
1610      if (*mangled == 'Z')
1611	mangled++;
1612      else
1613	{
1614	  /* Discard the declaration or return type.  */
1615	  string type;
1616
1617	  string_init (&type);
1618	  mangled = dlang_type (&type, mangled, info);
1619	  string_delete (&type);
1620	}
1621    }
1622
1623  return mangled;
1624}
1625
1626/* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1627   SUFFIX_MODIFIERS is 1 if we are printing modifiers on this after the symbol.
1628   Returns the remaining signature on success or NULL on failure.  */
1629static const char *
1630dlang_parse_qualified (string *decl, const char *mangled,
1631		       struct dlang_info *info, int suffix_modifiers)
1632{
1633  /* Qualified names are identifiers separated by their encoded length.
1634     Nested functions also encode their argument types without specifying
1635     what they return.
1636
1637	QualifiedName:
1638	    SymbolFunctionName
1639	    SymbolFunctionName QualifiedName
1640	    ^
1641
1642	SymbolFunctionName:
1643	    SymbolName
1644	    SymbolName TypeFunctionNoReturn
1645	    SymbolName M TypeFunctionNoReturn
1646	    SymbolName M TypeModifiers TypeFunctionNoReturn
1647
1648     The start pointer should be at the above location.
1649   */
1650  size_t n = 0;
1651  do
1652    {
1653      /* Skip over anonymous symbols.  */
1654      if (*mangled == '0')
1655      {
1656	do
1657	  mangled++;
1658	while (*mangled == '0');
1659
1660	continue;
1661      }
1662
1663      if (n++)
1664	string_append (decl, ".");
1665
1666      mangled = dlang_identifier (decl, mangled, info);
1667
1668      /* Consume the encoded arguments.  However if this is not followed by the
1669	 next encoded length or mangle type, then this is not a continuation of
1670	 a qualified name, in which case we backtrack and return the current
1671	 unconsumed position of the mangled decl.  */
1672      if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
1673	{
1674	  string mods;
1675	  const char *start = mangled;
1676	  int saved = string_length (decl);
1677
1678	  /* Save the type modifiers for appending at the end if needed.  */
1679	  string_init (&mods);
1680
1681	  /* Skip over 'this' parameter and type modifiers.  */
1682	  if (*mangled == 'M')
1683	    {
1684	      mangled++;
1685	      mangled = dlang_type_modifiers (&mods, mangled);
1686	      string_setlength (decl, saved);
1687	    }
1688
1689	  mangled = dlang_function_type_noreturn (decl, NULL, NULL,
1690						  mangled, info);
1691	  if (suffix_modifiers)
1692	    string_appendn (decl, mods.b, string_length (&mods));
1693
1694	  if (mangled == NULL || *mangled == '\0')
1695	    {
1696	      /* Did not match the rule we were looking for.  */
1697	      mangled = start;
1698	      string_setlength (decl, saved);
1699	    }
1700
1701	  string_delete (&mods);
1702	}
1703    }
1704  while (mangled && dlang_symbol_name_p (mangled, info));
1705
1706  return mangled;
1707}
1708
1709/* Demangle the tuple from MANGLED and append it to DECL.
1710   Return the remaining string on success or NULL on failure.  */
1711static const char *
1712dlang_parse_tuple (string *decl, const char *mangled, struct dlang_info *info)
1713{
1714  unsigned long elements;
1715
1716  mangled = dlang_number (mangled, &elements);
1717  if (mangled == NULL)
1718    return NULL;
1719
1720  string_append (decl, "Tuple!(");
1721
1722  while (elements--)
1723    {
1724      mangled = dlang_type (decl, mangled, info);
1725      if (mangled == NULL)
1726	return NULL;
1727
1728      if (elements != 0)
1729	string_append (decl, ", ");
1730    }
1731
1732  string_append (decl, ")");
1733  return mangled;
1734}
1735
1736/* Demangle the template symbol parameter from MANGLED and append it to DECL.
1737   Return the remaining string on success or NULL on failure.  */
1738static const char *
1739dlang_template_symbol_param (string *decl, const char *mangled,
1740			     struct dlang_info *info)
1741{
1742  if (strncmp (mangled, "_D", 2) == 0
1743      && dlang_symbol_name_p (mangled + 2, info))
1744    return dlang_parse_mangle (decl, mangled, info);
1745
1746  if (*mangled == 'Q')
1747    return dlang_parse_qualified (decl, mangled, info, 0);
1748
1749  unsigned long len;
1750  const char *endptr = dlang_number (mangled, &len);
1751
1752  if (endptr == NULL || len == 0)
1753    return NULL;
1754
1755  /* In template parameter symbols generated by the frontend up to 2.076,
1756     the symbol length is encoded and the first character of the mangled
1757     name can be a digit.  This causes ambiguity issues because the digits
1758     of the two numbers are adjacent.  */
1759  long psize = len;
1760  const char *pend;
1761  int saved = string_length (decl);
1762
1763  /* Work backwards until a match is found.  */
1764  for (pend = endptr; endptr != NULL; pend--)
1765    {
1766      mangled = pend;
1767
1768      /* Reached the beginning of the pointer to the name length,
1769	 try parsing the entire symbol.  */
1770      if (psize == 0)
1771	{
1772	  psize = len;
1773	  pend = endptr;
1774	  endptr = NULL;
1775	}
1776
1777      /* Check whether template parameter is a function with a valid
1778	 return type or an untyped identifier.  */
1779      if (dlang_symbol_name_p (mangled, info))
1780	mangled = dlang_parse_qualified (decl, mangled, info, 0);
1781      else if (strncmp (mangled, "_D", 2) == 0
1782	       && dlang_symbol_name_p (mangled + 2, info))
1783	mangled = dlang_parse_mangle (decl, mangled, info);
1784
1785      /* Check for name length mismatch.  */
1786      if (mangled && (endptr == NULL || (mangled - pend) == psize))
1787	return mangled;
1788
1789      psize /= 10;
1790      string_setlength (decl, saved);
1791    }
1792
1793  /* No match on any combinations.  */
1794  return NULL;
1795}
1796
1797/* Demangle the argument list from MANGLED and append it to DECL.
1798   Return the remaining string on success or NULL on failure.  */
1799static const char *
1800dlang_template_args (string *decl, const char *mangled, struct dlang_info *info)
1801{
1802  size_t n = 0;
1803
1804  while (mangled && *mangled != '\0')
1805    {
1806      switch (*mangled)
1807	{
1808	case 'Z': /* End of parameter list.  */
1809	  mangled++;
1810	  return mangled;
1811	}
1812
1813      if (n++)
1814	string_append (decl, ", ");
1815
1816      /* Skip over specialised template prefix.  */
1817      if (*mangled == 'H')
1818	mangled++;
1819
1820      switch (*mangled)
1821	{
1822	case 'S': /* Symbol parameter.  */
1823	  mangled++;
1824	  mangled = dlang_template_symbol_param (decl, mangled, info);
1825	  break;
1826	case 'T': /* Type parameter.  */
1827	  mangled++;
1828	  mangled = dlang_type (decl, mangled, info);
1829	  break;
1830	case 'V': /* Value parameter.  */
1831	{
1832	  string name;
1833	  char type;
1834
1835	  /* Peek at the type.  */
1836	  mangled++;
1837	  type = *mangled;
1838
1839	  if (type == 'Q')
1840	    {
1841	      /* Value type is a back reference, peek at the real type.  */
1842	      const char *backref;
1843	      if (dlang_backref (mangled, &backref, info) == NULL)
1844		return NULL;
1845
1846	      type = *backref;
1847	    }
1848
1849	  /* In the few instances where the type is actually desired in
1850	     the output, it should precede the value from dlang_value.  */
1851	  string_init (&name);
1852	  mangled = dlang_type (&name, mangled, info);
1853	  string_need (&name, 1);
1854	  *(name.p) = '\0';
1855
1856	  mangled = dlang_value (decl, mangled, name.b, type, info);
1857	  string_delete (&name);
1858	  break;
1859	}
1860	case 'X': /* Externally mangled parameter.  */
1861	{
1862	  unsigned long len;
1863	  const char *endptr;
1864
1865	  mangled++;
1866	  endptr = dlang_number (mangled, &len);
1867	  if (endptr == NULL || strlen (endptr) < len)
1868	    return NULL;
1869
1870	  string_appendn (decl, endptr, len);
1871	  mangled = endptr + len;
1872	  break;
1873	}
1874	default:
1875	  return NULL;
1876	}
1877    }
1878
1879  return mangled;
1880}
1881
1882/* Extract and demangle the template symbol in MANGLED, expected to
1883   be made up of LEN characters (-1 if unknown), and append it to DECL.
1884   Returns the remaining signature on success or NULL on failure.  */
1885static const char *
1886dlang_parse_template (string *decl, const char *mangled,
1887		      struct dlang_info *info, unsigned long len)
1888{
1889  const char *start = mangled;
1890  string args;
1891
1892  /* Template instance names have the types and values of its parameters
1893     encoded into it.
1894
1895	TemplateInstanceName:
1896	    Number __T LName TemplateArgs Z
1897	    Number __U LName TemplateArgs Z
1898		   ^
1899     The start pointer should be at the above location, and LEN should be
1900     the value of the decoded number.
1901   */
1902
1903  /* Template symbol.  */
1904  if (!dlang_symbol_name_p (mangled + 3, info) || mangled[3] == '0')
1905    return NULL;
1906
1907  mangled += 3;
1908
1909  /* Template identifier.  */
1910  mangled = dlang_identifier (decl, mangled, info);
1911
1912  /* Template arguments.  */
1913  string_init (&args);
1914  mangled = dlang_template_args (&args, mangled, info);
1915
1916  string_append (decl, "!(");
1917  string_appendn (decl, args.b, string_length (&args));
1918  string_append (decl, ")");
1919
1920  string_delete (&args);
1921
1922  /* Check for template name length mismatch.  */
1923  if (len != TEMPLATE_LENGTH_UNKNOWN
1924      && mangled
1925      && (unsigned long) (mangled - start) != len)
1926    return NULL;
1927
1928  return mangled;
1929}
1930
1931/* Initialize the information structure we use to pass around information.  */
1932static void
1933dlang_demangle_init_info (const char *mangled, int last_backref,
1934			  struct dlang_info *info)
1935{
1936  info->s = mangled;
1937  info->last_backref = last_backref;
1938}
1939
1940/* Extract and demangle the symbol in MANGLED.  Returns the demangled
1941   signature on success or NULL on failure.  */
1942
1943char *
1944dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1945{
1946  string decl;
1947  char *demangled = NULL;
1948
1949  if (mangled == NULL || *mangled == '\0')
1950    return NULL;
1951
1952  if (strncmp (mangled, "_D", 2) != 0)
1953    return NULL;
1954
1955  string_init (&decl);
1956
1957  if (strcmp (mangled, "_Dmain") == 0)
1958    {
1959      string_append (&decl, "D main");
1960    }
1961  else
1962    {
1963      struct dlang_info info;
1964
1965      dlang_demangle_init_info (mangled, strlen (mangled), &info);
1966      mangled = dlang_parse_mangle (&decl, mangled, &info);
1967
1968      /* Check that the entire symbol was successfully demangled.  */
1969      if (mangled == NULL || *mangled != '\0')
1970	string_delete (&decl);
1971    }
1972
1973  if (string_length (&decl) > 0)
1974    {
1975      string_need (&decl, 1);
1976      *(decl.p) = '\0';
1977      demangled = decl.b;
1978    }
1979
1980  return demangled;
1981}
1982
1983