(root)/
gcc-13.2.0/
libiberty/
d-demangle.c
       1  /* Demangler for the D programming language
       2     Copyright (C) 2014-2023 Free Software Foundation, Inc.
       3     Written by Iain Buclaw (ibuclaw@gdcproject.org)
       4  
       5  This file is part of the libiberty library.
       6  Libiberty is free software; you can redistribute it and/or
       7  modify it under the terms of the GNU Library General Public
       8  License as published by the Free Software Foundation; either
       9  version 2 of the License, or (at your option) any later version.
      10  
      11  In addition to the permissions in the GNU Library General Public
      12  License, the Free Software Foundation gives you unlimited permission
      13  to link the compiled version of this file into combinations with other
      14  programs, and to distribute those combinations without any restriction
      15  coming from the use of this file.  (The Library Public License
      16  restrictions do apply in other respects; for example, they cover
      17  modification of the file, and distribution when not linked into a
      18  combined executable.)
      19  
      20  Libiberty is distributed in the hope that it will be useful,
      21  but WITHOUT ANY WARRANTY; without even the implied warranty of
      22  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      23  Library General Public License for more details.
      24  
      25  You should have received a copy of the GNU Library General Public
      26  License along with libiberty; see the file COPYING.LIB.
      27  If not, see <http://www.gnu.org/licenses/>.  */
      28  
      29  /* This file exports one function; dlang_demangle.  */
      30  
      31  #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