Home | History | Annotate | Line # | Download | only in libiberty
      1 /* Demangler for the D programming language
      2    Copyright (C) 2014-2024 Free Software Foundation, Inc.
      3    Written by Iain Buclaw (ibuclaw (at) 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 #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 
     60 typedef 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 
     67 static void
     68 string_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 
     92 static void
     93 string_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 
    102 static void
    103 string_init (string *s)
    104 {
    105   s->b = s->p = s->e = NULL;
    106 }
    107 
    108 static int
    109 string_length (string *s)
    110 {
    111   if (s->p == s->b)
    112     {
    113       return 0;
    114     }
    115   return s->p - s->b;
    116 }
    117 
    118 static void
    119 string_setlength (string *s, int n)
    120 {
    121   if (n - string_length (s) < 0)
    122     {
    123       s->p = s->b + n;
    124     }
    125 }
    126 
    127 static void
    128 string_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 
    136 static void
    137 string_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 
    147 static void
    148 string_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 
    164 static void
    165 string_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.  */
    174 struct 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 */
    186 static const char *dlang_function_type (string *, const char *,
    187 					struct dlang_info *);
    188 
    189 static const char *dlang_function_args (string *, const char *,
    190 					struct dlang_info *);
    191 
    192 static const char *dlang_type (string *, const char *, struct dlang_info *);
    193 
    194 static const char *dlang_value (string *, const char *, const char *, char,
    195 				struct dlang_info *);
    196 
    197 static const char *dlang_parse_qualified (string *, const char *,
    198 					  struct dlang_info *, int);
    199 
    200 static const char *dlang_parse_mangle (string *, const char *,
    201 				       struct dlang_info *);
    202 
    203 static const char *dlang_parse_tuple (string *, const char *,
    204 				      struct dlang_info *);
    205 
    206 static const char *dlang_parse_template (string *, const char *,
    207 					 struct dlang_info *, unsigned long);
    208 
    209 static 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.  */
    215 static const char *
    216 dlang_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.  */
    245 static const char *
    246 dlang_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.  */
    273 static int
    274 dlang_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.  */
    290 static const char *
    291 dlang_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.  */
    338 static const char *
    339 dlang_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.  */
    366 static const char *
    367 dlang_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.  */
    397 static const char *
    398 dlang_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.  */
    436 static int
    437 dlang_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.  */
    461 static const char *
    462 dlang_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.  */
    501 static const char *
    502 dlang_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.  */
    539 static const char *
    540 dlang_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.  */
    617 static const char *
    618 dlang_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.  */
    641 static const char *
    642 dlang_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.  */
    678 static const char *
    679 dlang_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.  */
    749 static const char *
    750 dlang_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.  */
   1016 static const char *
   1017 dlang_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.  */
   1072 static const char *
   1073 dlang_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.  */
   1163 static const char *
   1164 dlang_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.  */
   1274 static const char *
   1275 dlang_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.  */
   1343 static const char *
   1344 dlang_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.  */
   1408 static const char *
   1409 dlang_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.  */
   1435 static const char *
   1436 dlang_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.  */
   1467 static const char *
   1468 dlang_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.  */
   1497 static const char *
   1498 dlang_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.  */
   1589 static const char *
   1590 dlang_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.  */
   1629 static const char *
   1630 dlang_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.  */
   1711 static const char *
   1712 dlang_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.  */
   1738 static const char *
   1739 dlang_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.  */
   1799 static const char *
   1800 dlang_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.  */
   1885 static const char *
   1886 dlang_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.  */
   1932 static void
   1933 dlang_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 
   1943 char *
   1944 dlang_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