Introduce tui_source_window_base::set_contents method
[external/binutils.git] / libiberty / d-demangle.c
1 /* Demangler for the D programming language
2    Copyright (C) 2014-2019 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
35 #include "safe-ctype.h"
36
37 #include <sys/types.h>
38 #include <string.h>
39 #include <stdio.h>
40
41 #ifdef HAVE_STDLIB_H
42 #include <stdlib.h>
43 #endif
44
45 #include <demangle.h>
46 #include "libiberty.h"
47
48 /* A mini string-handling package */
49
50 typedef struct string           /* Beware: these aren't required to be */
51 {                               /*  '\0' terminated.  */
52   char *b;                      /* pointer to start of string */
53   char *p;                      /* pointer after last character */
54   char *e;                      /* pointer after end of allocated space */
55 } string;
56
57 static void
58 string_need (string *s, int n)
59 {
60   int tem;
61
62   if (s->b == NULL)
63     {
64       if (n < 32)
65         {
66           n = 32;
67         }
68       s->p = s->b = XNEWVEC (char, n);
69       s->e = s->b + n;
70     }
71   else if (s->e - s->p < n)
72     {
73       tem = s->p - s->b;
74       n += tem;
75       n *= 2;
76       s->b = XRESIZEVEC (char, s->b, n);
77       s->p = s->b + tem;
78       s->e = s->b + n;
79     }
80 }
81
82 static void
83 string_delete (string *s)
84 {
85   if (s->b != NULL)
86     {
87       XDELETEVEC (s->b);
88       s->b = s->e = s->p = NULL;
89     }
90 }
91
92 static void
93 string_init (string *s)
94 {
95   s->b = s->p = s->e = NULL;
96 }
97
98 static int
99 string_length (string *s)
100 {
101   if (s->p == s->b)
102     {
103       return 0;
104     }
105   return s->p - s->b;
106 }
107
108 static void
109 string_setlength (string *s, int n)
110 {
111   if (n - string_length (s) < 0)
112     {
113       s->p = s->b + n;
114     }
115 }
116
117 static void
118 string_append (string *p, const char *s)
119 {
120   int n = strlen (s);
121   string_need (p, n);
122   memcpy (p->p, s, n);
123   p->p += n;
124 }
125
126 static void
127 string_appendn (string *p, const char *s, int n)
128 {
129   if (n != 0)
130     {
131       string_need (p, n);
132       memcpy (p->p, s, n);
133       p->p += n;
134     }
135 }
136
137 static void
138 string_prependn (string *p, const char *s, int n)
139 {
140   char *q;
141
142   if (n != 0)
143     {
144       string_need (p, n);
145       for (q = p->p - 1; q >= p->b; q--)
146         {
147           q[n] = q[0];
148         }
149       memcpy (p->b, s, n);
150       p->p += n;
151     }
152 }
153
154 static void
155 string_prepend (string *p, const char *s)
156 {
157   if (s != NULL && *s != '\0')
158     {
159       string_prependn (p, s, strlen (s));
160     }
161 }
162
163 /* What kinds of symbol we could be parsing.  */
164 enum dlang_symbol_kinds
165 {
166   /* Top-level symbol, needs it's type checked.  */
167   dlang_top_level,
168   /* Function symbol, needs it's type checked.   */
169   dlang_function,
170   /* Strongly typed name, such as for classes, structs and enums.  */
171   dlang_type_name,
172   /* Template identifier.  */
173   dlang_template_ident,
174   /* Template symbol parameter.  */
175   dlang_template_param
176 };
177
178 /* Prototypes for forward referenced functions */
179 static const char *dlang_function_args (string *, const char *);
180
181 static const char *dlang_type (string *, const char *);
182
183 static const char *dlang_value (string *, const char *, const char *, char);
184
185 static const char *dlang_parse_qualified (string *, const char *,
186                                           enum dlang_symbol_kinds);
187
188 static const char *dlang_parse_mangle (string *, const char *,
189                                        enum dlang_symbol_kinds);
190
191 static const char *dlang_parse_tuple (string *, const char *);
192
193 static const char *dlang_parse_template (string *, const char *, long);
194
195
196 /* Extract the number from MANGLED, and assign the result to RET.
197    Return the remaining string on success or NULL on failure.  */
198 static const char *
199 dlang_number (const char *mangled, long *ret)
200 {
201   /* Return NULL if trying to extract something that isn't a digit.  */
202   if (mangled == NULL || !ISDIGIT (*mangled))
203     return NULL;
204
205   (*ret) = 0;
206
207   while (ISDIGIT (*mangled))
208     {
209       (*ret) *= 10;
210
211       /* If an overflow occured when multiplying by ten, the result
212          will not be a multiple of ten.  */
213       if ((*ret % 10) != 0)
214         return NULL;
215
216       (*ret) += mangled[0] - '0';
217       mangled++;
218     }
219
220   if (*mangled == '\0' || *ret < 0)
221     return NULL;
222
223   return mangled;
224 }
225
226 /* Extract the hex-digit from MANGLED, and assign the result to RET.
227    Return the remaining string on success or NULL on failure.  */
228 static const char *
229 dlang_hexdigit (const char *mangled, char *ret)
230 {
231   char c;
232
233   /* Return NULL if trying to extract something that isn't a hexdigit.  */
234   if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1]))
235     return NULL;
236
237   c = mangled[0];
238   if (!ISDIGIT (c))
239     (*ret) = (c - (ISUPPER (c) ? 'A' : 'a') + 10);
240   else
241     (*ret) = (c - '0');
242
243   c = mangled[1];
244   if (!ISDIGIT (c))
245     (*ret) = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10);
246   else
247     (*ret) = (*ret << 4) | (c - '0');
248
249   mangled += 2;
250
251   return mangled;
252 }
253
254 /* Extract the function calling convention from MANGLED and
255    return 1 on success or 0 on failure.  */
256 static int
257 dlang_call_convention_p (const char *mangled)
258 {
259   switch (*mangled)
260     {
261     case 'F': case 'U': case 'V':
262     case 'W': case 'R': case 'Y':
263       return 1;
264
265     default:
266       return 0;
267     }
268 }
269
270 /* Demangle the calling convention from MANGLED and append it to DECL.
271    Return the remaining string on success or NULL on failure.  */
272 static const char *
273 dlang_call_convention (string *decl, const char *mangled)
274 {
275   if (mangled == NULL || *mangled == '\0')
276     return NULL;
277
278   switch (*mangled)
279     {
280     case 'F': /* (D) */
281       mangled++;
282       break;
283     case 'U': /* (C) */
284       mangled++;
285       string_append (decl, "extern(C) ");
286       break;
287     case 'W': /* (Windows) */
288       mangled++;
289       string_append (decl, "extern(Windows) ");
290       break;
291     case 'V': /* (Pascal) */
292       mangled++;
293       string_append (decl, "extern(Pascal) ");
294       break;
295     case 'R': /* (C++) */
296       mangled++;
297       string_append (decl, "extern(C++) ");
298       break;
299     case 'Y': /* (Objective-C) */
300       mangled++;
301       string_append (decl, "extern(Objective-C) ");
302       break;
303     default:
304       return NULL;
305     }
306
307   return mangled;
308 }
309
310 /* Extract the type modifiers from MANGLED and append them to DECL.
311    Returns the remaining signature on success or NULL on failure.  */
312 static const char *
313 dlang_type_modifiers (string *decl, const char *mangled)
314 {
315   if (mangled == NULL || *mangled == '\0')
316     return NULL;
317
318   switch (*mangled)
319     {
320     case 'x': /* const */
321       mangled++;
322       string_append (decl, " const");
323       return mangled;
324     case 'y': /* immutable */
325       mangled++;
326       string_append (decl, " immutable");
327       return mangled;
328     case 'O': /* shared */
329       mangled++;
330       string_append (decl, " shared");
331       return dlang_type_modifiers (decl, mangled);
332     case 'N':
333       mangled++;
334       if (*mangled == 'g') /* wild */
335         {
336           mangled++;
337           string_append (decl, " inout");
338           return dlang_type_modifiers (decl, mangled);
339         }
340       else
341         return NULL;
342
343     default:
344       return mangled;
345     }
346 }
347
348 /* Demangle the D function attributes from MANGLED and append it to DECL.
349    Return the remaining string on success or NULL on failure.  */
350 static const char *
351 dlang_attributes (string *decl, const char *mangled)
352 {
353   if (mangled == NULL || *mangled == '\0')
354     return NULL;
355
356   while (*mangled == 'N')
357     {
358       mangled++;
359       switch (*mangled)
360         {
361         case 'a': /* pure */
362           mangled++;
363           string_append (decl, "pure ");
364           continue;
365         case 'b': /* nothrow */
366           mangled++;
367           string_append (decl, "nothrow ");
368           continue;
369         case 'c': /* ref */
370           mangled++;
371           string_append (decl, "ref ");
372           continue;
373         case 'd': /* @property */
374           mangled++;
375           string_append (decl, "@property ");
376           continue;
377         case 'e': /* @trusted */
378           mangled++;
379           string_append (decl, "@trusted ");
380           continue;
381         case 'f': /* @safe */
382           mangled++;
383           string_append (decl, "@safe ");
384           continue;
385         case 'g':
386         case 'h':
387         case 'k':
388           /* inout parameter is represented as 'Ng'.
389              vector parameter is represented as 'Nh'.
390              return paramenter is represented as 'Nk'.
391              If we see this, then we know we're really in the
392              parameter list.  Rewind and break.  */
393           mangled--;
394           break;
395         case 'i': /* @nogc */
396           mangled++;
397           string_append (decl, "@nogc ");
398           continue;
399         case 'j': /* return */
400           mangled++;
401           string_append (decl, "return ");
402           continue;
403         case 'l': /* scope */
404           mangled++;
405           string_append (decl, "scope ");
406           continue;
407
408         default: /* unknown attribute */
409           return NULL;
410         }
411       break;
412     }
413
414   return mangled;
415 }
416
417 /* Demangle the function type from MANGLED and append it to DECL.
418    Return the remaining string on success or NULL on failure.  */
419 static const char *
420 dlang_function_type (string *decl, const char *mangled)
421 {
422   string attr, args, type;
423   size_t szattr, szargs, sztype;
424
425   if (mangled == NULL || *mangled == '\0')
426     return NULL;
427
428   /* The order of the mangled string is:
429         CallConvention FuncAttrs Arguments ArgClose Type
430
431      The demangled string is re-ordered as:
432         CallConvention Type Arguments FuncAttrs
433    */
434   string_init (&attr);
435   string_init (&args);
436   string_init (&type);
437
438   /* Function call convention.  */
439   mangled = dlang_call_convention (decl, mangled);
440
441   /* Function attributes.  */
442   mangled = dlang_attributes (&attr, mangled);
443   szattr = string_length (&attr);
444
445   /* Function arguments.  */
446   mangled = dlang_function_args (&args, mangled);
447   szargs = string_length (&args);
448
449   /* Function return type.  */
450   mangled = dlang_type (&type, mangled);
451   sztype = string_length (&type);
452
453   /* Append to decl in order. */
454   string_appendn (decl, type.b, sztype);
455   string_append (decl, "(");
456   string_appendn (decl, args.b, szargs);
457   string_append (decl, ") ");
458   string_appendn (decl, attr.b, szattr);
459
460   string_delete (&attr);
461   string_delete (&args);
462   string_delete (&type);
463   return mangled;
464 }
465
466 /* Demangle the argument list from MANGLED and append it to DECL.
467    Return the remaining string on success or NULL on failure.  */
468 static const char *
469 dlang_function_args (string *decl, const char *mangled)
470 {
471   size_t n = 0;
472
473   while (mangled && *mangled != '\0')
474     {
475       switch (*mangled)
476         {
477         case 'X': /* (variadic T t...) style.  */
478           mangled++;
479           string_append (decl, "...");
480           return mangled;
481         case 'Y': /* (variadic T t, ...) style.  */
482           mangled++;
483           if (n != 0)
484             string_append (decl, ", ");
485           string_append (decl, "...");
486           return mangled;
487         case 'Z': /* Normal function.  */
488           mangled++;
489           return mangled;
490         }
491
492       if (n++)
493         string_append (decl, ", ");
494
495       if (*mangled == 'M') /* scope(T) */
496         {
497           mangled++;
498           string_append (decl, "scope ");
499         }
500
501       if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
502         {
503           mangled += 2;
504           string_append (decl, "return ");
505         }
506
507       switch (*mangled)
508         {
509         case 'J': /* out(T) */
510           mangled++;
511           string_append (decl, "out ");
512           break;
513         case 'K': /* ref(T) */
514           mangled++;
515           string_append (decl, "ref ");
516           break;
517         case 'L': /* lazy(T) */
518           mangled++;
519           string_append (decl, "lazy ");
520           break;
521         }
522       mangled = dlang_type (decl, mangled);
523     }
524
525   return mangled;
526 }
527
528 /* Demangle the type from MANGLED and append it to DECL.
529    Return the remaining string on success or NULL on failure.  */
530 static const char *
531 dlang_type (string *decl, const char *mangled)
532 {
533   if (mangled == NULL || *mangled == '\0')
534     return NULL;
535
536   switch (*mangled)
537     {
538     case 'O': /* shared(T) */
539       mangled++;
540       string_append (decl, "shared(");
541       mangled = dlang_type (decl, mangled);
542       string_append (decl, ")");
543       return mangled;
544     case 'x': /* const(T) */
545       mangled++;
546       string_append (decl, "const(");
547       mangled = dlang_type (decl, mangled);
548       string_append (decl, ")");
549       return mangled;
550     case 'y': /* immutable(T) */
551       mangled++;
552       string_append (decl, "immutable(");
553       mangled = dlang_type (decl, mangled);
554       string_append (decl, ")");
555       return mangled;
556     case 'N':
557       mangled++;
558       if (*mangled == 'g') /* wild(T) */
559         {
560           mangled++;
561           string_append (decl, "inout(");
562           mangled = dlang_type (decl, mangled);
563           string_append (decl, ")");
564           return mangled;
565         }
566       else if (*mangled == 'h') /* vector(T) */
567         {
568           mangled++;
569           string_append (decl, "__vector(");
570           mangled = dlang_type (decl, mangled);
571           string_append (decl, ")");
572           return mangled;
573         }
574       else
575         return NULL;
576     case 'A': /* dynamic array (T[]) */
577       mangled++;
578       mangled = dlang_type (decl, mangled);
579       string_append (decl, "[]");
580       return mangled;
581     case 'G': /* static array (T[N]) */
582     {
583       const char *numptr;
584       size_t num = 0;
585       mangled++;
586
587       numptr = mangled;
588       while (ISDIGIT (*mangled))
589         {
590           num++;
591           mangled++;
592         }
593       mangled = dlang_type (decl, mangled);
594       string_append (decl, "[");
595       string_appendn (decl, numptr, num);
596       string_append (decl, "]");
597       return mangled;
598     }
599     case 'H': /* associative array (T[T]) */
600     {
601       string type;
602       size_t sztype;
603       mangled++;
604
605       string_init (&type);
606       mangled = dlang_type (&type, mangled);
607       sztype = string_length (&type);
608
609       mangled = dlang_type (decl, mangled);
610       string_append (decl, "[");
611       string_appendn (decl, type.b, sztype);
612       string_append (decl, "]");
613
614       string_delete (&type);
615       return mangled;
616     }
617     case 'P': /* pointer (T*) */
618       mangled++;
619       if (!dlang_call_convention_p (mangled))
620         {
621           mangled = dlang_type (decl, mangled);
622           string_append (decl, "*");
623           return mangled;
624         }
625       /* Fall through */
626     case 'F': /* function T (D) */
627     case 'U': /* function T (C) */
628     case 'W': /* function T (Windows) */
629     case 'V': /* function T (Pascal) */
630     case 'R': /* function T (C++) */
631     case 'Y': /* function T (Objective-C) */
632       /* Function pointer types don't include the trailing asterisk.  */
633       mangled = dlang_function_type (decl, mangled);
634       string_append (decl, "function");
635       return mangled;
636     case 'I': /* ident T */
637     case 'C': /* class T */
638     case 'S': /* struct T */
639     case 'E': /* enum T */
640     case 'T': /* typedef T */
641       mangled++;
642       return dlang_parse_qualified (decl, mangled, dlang_type_name);
643     case 'D': /* delegate T */
644     {
645       string mods;
646       size_t szmods;
647       mangled++;
648
649       string_init (&mods);
650       mangled = dlang_type_modifiers (&mods, mangled);
651       szmods = string_length (&mods);
652
653       mangled = dlang_function_type (decl, mangled);
654       string_append (decl, "delegate");
655       string_appendn (decl, mods.b, szmods);
656
657       string_delete (&mods);
658       return mangled;
659     }
660     case 'B': /* tuple T */
661       mangled++;
662       return dlang_parse_tuple (decl, mangled);
663
664     /* Basic types */
665     case 'n':
666       mangled++;
667       string_append (decl, "none");
668       return mangled;
669     case 'v':
670       mangled++;
671       string_append (decl, "void");
672       return mangled;
673     case 'g':
674       mangled++;
675       string_append (decl, "byte");
676       return mangled;
677     case 'h':
678       mangled++;
679       string_append (decl, "ubyte");
680       return mangled;
681     case 's':
682       mangled++;
683       string_append (decl, "short");
684       return mangled;
685     case 't':
686       mangled++;
687       string_append (decl, "ushort");
688       return mangled;
689     case 'i':
690       mangled++;
691       string_append (decl, "int");
692       return mangled;
693     case 'k':
694       mangled++;
695       string_append (decl, "uint");
696       return mangled;
697     case 'l':
698       mangled++;
699       string_append (decl, "long");
700       return mangled;
701     case 'm':
702       mangled++;
703       string_append (decl, "ulong");
704       return mangled;
705     case 'f':
706       mangled++;
707       string_append (decl, "float");
708       return mangled;
709     case 'd':
710       mangled++;
711       string_append (decl, "double");
712       return mangled;
713     case 'e':
714       mangled++;
715       string_append (decl, "real");
716       return mangled;
717
718     /* Imaginary and Complex types */
719     case 'o':
720       mangled++;
721       string_append (decl, "ifloat");
722       return mangled;
723     case 'p':
724       mangled++;
725       string_append (decl, "idouble");
726       return mangled;
727     case 'j':
728       mangled++;
729       string_append (decl, "ireal");
730       return mangled;
731     case 'q':
732       mangled++;
733       string_append (decl, "cfloat");
734       return mangled;
735     case 'r':
736       mangled++;
737       string_append (decl, "cdouble");
738       return mangled;
739     case 'c':
740       mangled++;
741       string_append (decl, "creal");
742       return mangled;
743
744     /* Other types */
745     case 'b':
746       mangled++;
747       string_append (decl, "bool");
748       return mangled;
749     case 'a':
750       mangled++;
751       string_append (decl, "char");
752       return mangled;
753     case 'u':
754       mangled++;
755       string_append (decl, "wchar");
756       return mangled;
757     case 'w':
758       mangled++;
759       string_append (decl, "dchar");
760       return mangled;
761     case 'z':
762       mangled++;
763       switch (*mangled)
764         {
765         case 'i':
766           mangled++;
767           string_append (decl, "cent");
768           return mangled;
769         case 'k':
770           mangled++;
771           string_append (decl, "ucent");
772           return mangled;
773         }
774       return NULL;
775
776     default: /* unhandled */
777       return NULL;
778     }
779 }
780
781 /* Extract the identifier from MANGLED and append it to DECL.
782    Return the remaining string on success or NULL on failure.  */
783 static const char *
784 dlang_identifier (string *decl, const char *mangled,
785                   enum dlang_symbol_kinds kind)
786 {
787   long len;
788   const char *endptr = dlang_number (mangled, &len);
789
790   if (endptr == NULL || len == 0)
791     return NULL;
792
793   /* In template parameter symbols, the first character of the mangled
794      name can be a digit.  This causes ambiguity issues because the
795      digits of the two numbers are adjacent.  */
796   if (kind == dlang_template_param)
797     {
798       long psize = len;
799       const char *pend;
800       int saved = string_length (decl);
801
802       /* Work backwards until a match is found.  */
803       for (pend = endptr; endptr != NULL; pend--)
804         {
805           mangled = pend;
806
807           /* Reached the beginning of the pointer to the name length,
808              try parsing the entire symbol.  */
809           if (psize == 0)
810             {
811               psize = len;
812               pend = endptr;
813               endptr = NULL;
814             }
815
816           /* Check whether template parameter is a function with a valid
817              return type or an untyped identifier.  */
818           if (ISDIGIT (*mangled))
819             mangled = dlang_parse_qualified (decl, mangled,
820                                              dlang_template_ident);
821           else if (strncmp (mangled, "_D", 2) == 0)
822             mangled = dlang_parse_mangle (decl, mangled, dlang_function);
823
824           /* Check for name length mismatch.  */
825           if (mangled && (mangled - pend) == psize)
826             return mangled;
827
828           psize /= 10;
829           string_setlength (decl, saved);
830         }
831
832       /* No match on any combinations.  */
833       return NULL;
834     }
835   else
836     {
837       if (strlen (endptr) < (size_t) len)
838         return NULL;
839
840       mangled = endptr;
841
842       /* May be a template instance.  */
843       if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
844           && (mangled[2] == 'T' || mangled[2] == 'U'))
845         return dlang_parse_template (decl, mangled, len);
846
847       switch (len)
848         {
849         case 6:
850           if (strncmp (mangled, "__ctor", len) == 0)
851             {
852               /* Constructor symbol for a class/struct.  */
853               string_append (decl, "this");
854               mangled += len;
855               return mangled;
856             }
857           else if (strncmp (mangled, "__dtor", len) == 0)
858             {
859               /* Destructor symbol for a class/struct.  */
860               string_append (decl, "~this");
861               mangled += len;
862               return mangled;
863             }
864           else if (strncmp (mangled, "__initZ", len+1) == 0)
865             {
866               /* The static initialiser for a given symbol.  */
867               string_prepend (decl, "initializer for ");
868               string_setlength (decl, string_length (decl) - 1);
869               mangled += len;
870               return mangled;
871             }
872           else if (strncmp (mangled, "__vtblZ", len+1) == 0)
873             {
874               /* The vtable symbol for a given class.  */
875               string_prepend (decl, "vtable for ");
876               string_setlength (decl, string_length (decl) - 1);
877               mangled += len;
878               return mangled;
879             }
880           break;
881
882         case 7:
883           if (strncmp (mangled, "__ClassZ", len+1) == 0)
884             {
885               /* The classinfo symbol for a given class.  */
886               string_prepend (decl, "ClassInfo for ");
887               string_setlength (decl, string_length (decl) - 1);
888               mangled += len;
889               return mangled;
890             }
891           break;
892
893         case 10:
894           if (strncmp (mangled, "__postblitMFZ", len+3) == 0)
895             {
896               /* Postblit symbol for a struct.  */
897               string_append (decl, "this(this)");
898               mangled += len + 3;
899               return mangled;
900             }
901           break;
902
903         case 11:
904           if (strncmp (mangled, "__InterfaceZ", len+1) == 0)
905             {
906               /* The interface symbol for a given class.  */
907               string_prepend (decl, "Interface for ");
908               string_setlength (decl, string_length (decl) - 1);
909               mangled += len;
910               return mangled;
911             }
912           break;
913
914         case 12:
915           if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0)
916             {
917               /* The ModuleInfo symbol for a given module.  */
918               string_prepend (decl, "ModuleInfo for ");
919               string_setlength (decl, string_length (decl) - 1);
920               mangled += len;
921               return mangled;
922             }
923           break;
924         }
925
926       string_appendn (decl, mangled, len);
927       mangled += len;
928     }
929
930   return mangled;
931 }
932
933 /* Extract the integer value from MANGLED and append it to DECL,
934    where TYPE is the type it should be represented as.
935    Return the remaining string on success or NULL on failure.  */
936 static const char *
937 dlang_parse_integer (string *decl, const char *mangled, char type)
938 {
939   if (type == 'a' || type == 'u' || type == 'w')
940     {
941       /* Parse character value.  */
942       char value[20];
943       int pos = sizeof(value);
944       int width = 0;
945       long val;
946
947       mangled = dlang_number (mangled, &val);
948       if (mangled == NULL)
949         return NULL;
950
951       string_append (decl, "'");
952
953       if (type == 'a' && val >= 0x20 && val < 0x7F)
954         {
955           /* Represent as a character literal.  */
956           char c = (char) val;
957           string_appendn (decl, &c, 1);
958         }
959       else
960         {
961           /* Represent as a hexadecimal value.  */
962           switch (type)
963             {
964             case 'a': /* char */
965               string_append (decl, "\\x");
966               width = 2;
967               break;
968             case 'u': /* wchar */
969               string_append (decl, "\\u");
970               width = 4;
971               break;
972             case 'w': /* dchar */
973               string_append (decl, "\\U");
974               width = 8;
975               break;
976             }
977
978           while (val > 0)
979             {
980               int digit = val % 16;
981
982               if (digit < 10)
983                 value[--pos] = (char)(digit + '0');
984               else
985                 value[--pos] = (char)((digit - 10) + 'a');
986
987               val /= 16;
988               width--;
989             }
990
991           for (; width > 0; width--)
992             value[--pos] = '0';
993
994           string_appendn (decl, &(value[pos]), sizeof(value) - pos);
995         }
996       string_append (decl, "'");
997     }
998   else if (type == 'b')
999     {
1000       /* Parse boolean value.  */
1001       long val;
1002
1003       mangled = dlang_number (mangled, &val);
1004       if (mangled == NULL)
1005         return NULL;
1006
1007       string_append (decl, val ? "true" : "false");
1008     }
1009   else
1010     {
1011       /* Parse integer value.  */
1012       const char *numptr = mangled;
1013       size_t num = 0;
1014
1015       if (! ISDIGIT (*mangled))
1016         return NULL;
1017
1018       while (ISDIGIT (*mangled))
1019         {
1020           num++;
1021           mangled++;
1022         }
1023       string_appendn (decl, numptr, num);
1024
1025       /* Append suffix.  */
1026       switch (type)
1027         {
1028         case 'h': /* ubyte */
1029         case 't': /* ushort */
1030         case 'k': /* uint */
1031           string_append (decl, "u");
1032           break;
1033         case 'l': /* long */
1034           string_append (decl, "L");
1035           break;
1036         case 'm': /* ulong */
1037           string_append (decl, "uL");
1038           break;
1039         }
1040     }
1041
1042   return mangled;
1043 }
1044
1045 /* Extract the floating-point value from MANGLED and append it to DECL.
1046    Return the remaining string on success or NULL on failure.  */
1047 static const char *
1048 dlang_parse_real (string *decl, const char *mangled)
1049 {
1050   /* Handle NAN and +-INF.  */
1051   if (strncmp (mangled, "NAN", 3) == 0)
1052     {
1053       string_append (decl, "NaN");
1054       mangled += 3;
1055       return mangled;
1056     }
1057   else if (strncmp (mangled, "INF", 3) == 0)
1058     {
1059       string_append (decl, "Inf");
1060       mangled += 3;
1061       return mangled;
1062     }
1063   else if (strncmp (mangled, "NINF", 4) == 0)
1064     {
1065       string_append (decl, "-Inf");
1066       mangled += 4;
1067       return mangled;
1068     }
1069
1070   /* Hexadecimal prefix and leading bit.  */
1071   if (*mangled == 'N')
1072     {
1073       string_append (decl, "-");
1074       mangled++;
1075     }
1076
1077   if (!ISXDIGIT (*mangled))
1078     return NULL;
1079
1080   string_append (decl, "0x");
1081   string_appendn (decl, mangled, 1);
1082   string_append (decl, ".");
1083   mangled++;
1084
1085   /* Significand.  */
1086   while (ISXDIGIT (*mangled))
1087     {
1088       string_appendn (decl, mangled, 1);
1089       mangled++;
1090     }
1091
1092   /* Exponent.  */
1093   if (*mangled != 'P')
1094     return NULL;
1095
1096   string_append (decl, "p");
1097   mangled++;
1098
1099   if (*mangled == 'N')
1100     {
1101       string_append (decl, "-");
1102       mangled++;
1103     }
1104
1105   while (ISDIGIT (*mangled))
1106     {
1107       string_appendn (decl, mangled, 1);
1108       mangled++;
1109     }
1110
1111   return mangled;
1112 }
1113
1114 /* Extract the string value from MANGLED and append it to DECL.
1115    Return the remaining string on success or NULL on failure.  */
1116 static const char *
1117 dlang_parse_string (string *decl, const char *mangled)
1118 {
1119   char type = *mangled;
1120   long len;
1121
1122   mangled++;
1123   mangled = dlang_number (mangled, &len);
1124   if (mangled == NULL || *mangled != '_')
1125     return NULL;
1126
1127   mangled++;
1128   string_append (decl, "\"");
1129   while (len--)
1130     {
1131       char val;
1132       const char *endptr = dlang_hexdigit (mangled, &val);
1133
1134       if (endptr == NULL)
1135         return NULL;
1136
1137       /* Sanitize white and non-printable characters.  */
1138       switch (val)
1139         {
1140         case ' ':
1141           string_append (decl, " ");
1142           break;
1143         case '\t':
1144           string_append (decl, "\\t");
1145           break;
1146         case '\n':
1147           string_append (decl, "\\n");
1148           break;
1149         case '\r':
1150           string_append (decl, "\\r");
1151           break;
1152         case '\f':
1153           string_append (decl, "\\f");
1154           break;
1155         case '\v':
1156           string_append (decl, "\\v");
1157           break;
1158
1159         default:
1160           if (ISPRINT (val))
1161             string_appendn (decl, &val, 1);
1162           else
1163             {
1164               string_append (decl, "\\x");
1165               string_appendn (decl, mangled, 2);
1166             }
1167         }
1168
1169       mangled = endptr;
1170     }
1171   string_append (decl, "\"");
1172
1173   if (type != 'a')
1174     string_appendn (decl, &type, 1);
1175
1176   return mangled;
1177 }
1178
1179 /* Extract the static array value from MANGLED and append it to DECL.
1180    Return the remaining string on success or NULL on failure.  */
1181 static const char *
1182 dlang_parse_arrayliteral (string *decl, const char *mangled)
1183 {
1184   long elements;
1185
1186   mangled = dlang_number (mangled, &elements);
1187   if (mangled == NULL)
1188     return NULL;
1189
1190   string_append (decl, "[");
1191   while (elements--)
1192     {
1193       mangled = dlang_value (decl, mangled, NULL, '\0');
1194       if (mangled == NULL)
1195         return NULL;
1196
1197       if (elements != 0)
1198         string_append (decl, ", ");
1199     }
1200
1201   string_append (decl, "]");
1202   return mangled;
1203 }
1204
1205 /* Extract the associative array value from MANGLED and append it to DECL.
1206    Return the remaining string on success or NULL on failure.  */
1207 static const char *
1208 dlang_parse_assocarray (string *decl, const char *mangled)
1209 {
1210   long elements;
1211
1212   mangled = dlang_number (mangled, &elements);
1213   if (mangled == NULL)
1214     return NULL;
1215
1216   string_append (decl, "[");
1217   while (elements--)
1218     {
1219       mangled = dlang_value (decl, mangled, NULL, '\0');
1220       if (mangled == NULL)
1221         return NULL;
1222
1223       string_append (decl, ":");
1224       mangled = dlang_value (decl, mangled, NULL, '\0');
1225       if (mangled == NULL)
1226         return NULL;
1227
1228       if (elements != 0)
1229         string_append (decl, ", ");
1230     }
1231
1232   string_append (decl, "]");
1233   return mangled;
1234 }
1235
1236 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1237    Return the remaining string on success or NULL on failure.  */
1238 static const char *
1239 dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1240 {
1241   long args;
1242
1243   mangled = dlang_number (mangled, &args);
1244   if (mangled == NULL)
1245     return NULL;
1246
1247   if (name != NULL)
1248     string_append (decl, name);
1249
1250   string_append (decl, "(");
1251   while (args--)
1252     {
1253       mangled = dlang_value (decl, mangled, NULL, '\0');
1254       if (mangled == NULL)
1255         return NULL;
1256
1257       if (args != 0)
1258         string_append (decl, ", ");
1259     }
1260
1261   string_append (decl, ")");
1262   return mangled;
1263 }
1264
1265 /* Extract the value from MANGLED and append it to DECL.
1266    Return the remaining string on success or NULL on failure.  */
1267 static const char *
1268 dlang_value (string *decl, const char *mangled, const char *name, char type)
1269 {
1270   if (mangled == NULL || *mangled == '\0')
1271     return NULL;
1272
1273   switch (*mangled)
1274     {
1275       /* Null value.  */
1276     case 'n':
1277       mangled++;
1278       string_append (decl, "null");
1279       break;
1280
1281       /* Integral values.  */
1282     case 'N':
1283       mangled++;
1284       string_append (decl, "-");
1285       mangled = dlang_parse_integer (decl, mangled, type);
1286       break;
1287
1288     case 'i':
1289       mangled++;
1290       /* Fall through */
1291
1292       /* There really should always be an `i' before encoded numbers, but there
1293          wasn't in early versions of D2, so this case range must remain for
1294          backwards compatibility.  */
1295     case '0': case '1': case '2': case '3': case '4':
1296     case '5': case '6': case '7': case '8': case '9':
1297       mangled = dlang_parse_integer (decl, mangled, type);
1298       break;
1299
1300       /* Real value.  */
1301     case 'e':
1302       mangled++;
1303       mangled = dlang_parse_real (decl, mangled);
1304       break;
1305
1306       /* Complex value.  */
1307     case 'c':
1308       mangled++;
1309       mangled = dlang_parse_real (decl, mangled);
1310       string_append (decl, "+");
1311       if (mangled == NULL || *mangled != 'c')
1312         return NULL;
1313       mangled++;
1314       mangled = dlang_parse_real (decl, mangled);
1315       string_append (decl, "i");
1316       break;
1317
1318       /* String values.  */
1319     case 'a': /* UTF8 */
1320     case 'w': /* UTF16 */
1321     case 'd': /* UTF32 */
1322       mangled = dlang_parse_string (decl, mangled);
1323       break;
1324
1325       /* Array values.  */
1326     case 'A':
1327       mangled++;
1328       if (type == 'H')
1329         mangled = dlang_parse_assocarray (decl, mangled);
1330       else
1331         mangled = dlang_parse_arrayliteral (decl, mangled);
1332       break;
1333
1334       /* Struct values.  */
1335     case 'S':
1336       mangled++;
1337       mangled = dlang_parse_structlit (decl, mangled, name);
1338       break;
1339
1340     default:
1341       return NULL;
1342     }
1343
1344   return mangled;
1345 }
1346
1347 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1348    Returns the remaining signature on success or NULL on failure.  */
1349 static const char *
1350 dlang_parse_mangle (string *decl, const char *mangled,
1351                     enum dlang_symbol_kinds kind)
1352 {
1353   /* A D mangled symbol is comprised of both scope and type information.
1354
1355         MangleName:
1356             _D QualifiedName Type
1357             _D QualifiedName M Type
1358             _D QualifiedName Z
1359             ^
1360      The caller should have guaranteed that the start pointer is at the
1361      above location.
1362    */
1363   mangled += 2;
1364
1365   mangled = dlang_parse_qualified (decl, mangled, dlang_top_level);
1366
1367   if (mangled != NULL)
1368     {
1369       /* Artificial symbols end with 'Z' and have no type.  */
1370       if (*mangled == 'Z')
1371         mangled++;
1372       else
1373         {
1374           string mods;
1375           int saved;
1376
1377           /* Skip over 'this' parameter.  */
1378           if (*mangled == 'M')
1379             mangled++;
1380
1381           /* Save the type modifiers for appending at the end if needed.  */
1382           string_init (&mods);
1383           mangled = dlang_type_modifiers (&mods, mangled);
1384
1385           if (mangled && dlang_call_convention_p (mangled))
1386             {
1387               /* Skip over calling convention and attributes.  */
1388               saved = string_length (decl);
1389               mangled = dlang_call_convention (decl, mangled);
1390               mangled = dlang_attributes (decl, mangled);
1391               string_setlength (decl, saved);
1392
1393               string_append (decl, "(");
1394               mangled = dlang_function_args (decl, mangled);
1395               string_append (decl, ")");
1396
1397               /* Add any const/immutable/shared modifier. */
1398               string_appendn (decl, mods.b, string_length (&mods));
1399             }
1400
1401           /* Consume the decl type of symbol.  */
1402           saved = string_length (decl);
1403           mangled = dlang_type (decl, mangled);
1404           string_setlength (decl, saved);
1405
1406           string_delete (&mods);
1407         }
1408     }
1409
1410   /* Check that the entire symbol was successfully demangled.  */
1411   if (kind == dlang_top_level)
1412     {
1413       if (mangled == NULL || *mangled != '\0')
1414         return NULL;
1415     }
1416
1417   return mangled;
1418 }
1419
1420 /* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1421    Returns the remaining signature on success or NULL on failure.  */
1422 static const char *
1423 dlang_parse_qualified (string *decl, const char *mangled,
1424                        enum dlang_symbol_kinds kind)
1425 {
1426   /* Qualified names are identifiers separated by their encoded length.
1427      Nested functions also encode their argument types without specifying
1428      what they return.
1429
1430         QualifiedName:
1431             SymbolName
1432             SymbolName QualifiedName
1433             SymbolName TypeFunctionNoReturn QualifiedName
1434             SymbolName M TypeModifiers TypeFunctionNoReturn QualifiedName
1435             ^
1436      The start pointer should be at the above location.
1437    */
1438   size_t n = 0;
1439   do
1440     {
1441       if (n++)
1442         string_append (decl, ".");
1443
1444       /* Skip over anonymous symbols.  */
1445       while (*mangled == '0')
1446         mangled++;
1447
1448       mangled = dlang_identifier (decl, mangled, kind);
1449
1450       /* Consume the encoded arguments.  However if this is not followed by the
1451          next encoded length, then this is not a continuation of a qualified
1452          name, in which case we backtrack and return the current unconsumed
1453          position of the mangled decl.  */
1454       if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
1455         {
1456           const char *start = mangled;
1457           int saved = string_length (decl);
1458
1459           /* Skip over 'this' parameter and type modifiers.  */
1460           if (*mangled == 'M')
1461             {
1462               mangled++;
1463               mangled = dlang_type_modifiers (decl, mangled);
1464               string_setlength (decl, saved);
1465             }
1466
1467           /* The rule we expect to match in the mangled string is:
1468
1469                 TypeFunctionNoReturn:
1470                     CallConvention FuncAttrs Arguments ArgClose
1471
1472              The calling convention and function attributes are not included
1473              in the demangled string.  */
1474           mangled = dlang_call_convention (decl, mangled);
1475           mangled = dlang_attributes (decl, mangled);
1476           string_setlength (decl, saved);
1477
1478           string_append (decl, "(");
1479           mangled = dlang_function_args (decl, mangled);
1480           string_append (decl, ")");
1481
1482           if (mangled == NULL || !ISDIGIT (*mangled))
1483             {
1484               /* Did not match the rule we were looking for.  */
1485               mangled = start;
1486               string_setlength (decl, saved);
1487             }
1488         }
1489     }
1490   while (mangled && ISDIGIT (*mangled));
1491
1492   return mangled;
1493 }
1494
1495 /* Demangle the tuple from MANGLED and append it to DECL.
1496    Return the remaining string on success or NULL on failure.  */
1497 static const char *
1498 dlang_parse_tuple (string *decl, const char *mangled)
1499 {
1500   long elements;
1501
1502   mangled = dlang_number (mangled, &elements);
1503   if (mangled == NULL)
1504     return NULL;
1505
1506   string_append (decl, "Tuple!(");
1507
1508   while (elements--)
1509     {
1510       mangled = dlang_type (decl, mangled);
1511       if (mangled == NULL)
1512         return NULL;
1513
1514       if (elements != 0)
1515         string_append (decl, ", ");
1516     }
1517
1518   string_append (decl, ")");
1519   return mangled;
1520 }
1521
1522 /* Demangle the argument list from MANGLED and append it to DECL.
1523    Return the remaining string on success or NULL on failure.  */
1524 static const char *
1525 dlang_template_args (string *decl, const char *mangled)
1526 {
1527   size_t n = 0;
1528
1529   while (mangled && *mangled != '\0')
1530     {
1531       switch (*mangled)
1532         {
1533         case 'Z': /* End of parameter list.  */
1534           mangled++;
1535           return mangled;
1536         }
1537
1538       if (n++)
1539         string_append (decl, ", ");
1540
1541       /* Skip over specialised template prefix.  */
1542       if (*mangled == 'H')
1543         mangled++;
1544
1545       switch (*mangled)
1546         {
1547         case 'S': /* Symbol parameter.  */
1548           mangled++;
1549           mangled = dlang_identifier (decl, mangled, dlang_template_param);
1550           break;
1551         case 'T': /* Type parameter.  */
1552           mangled++;
1553           mangled = dlang_type (decl, mangled);
1554           break;
1555         case 'V': /* Value parameter.  */
1556         {
1557           string name;
1558           char type;
1559
1560           /* Peek at the type.  */
1561           mangled++;
1562           type = *mangled;
1563
1564           /* In the few instances where the type is actually desired in
1565              the output, it should precede the value from dlang_value.  */
1566           string_init (&name);
1567           mangled = dlang_type (&name, mangled);
1568           string_need (&name, 1);
1569           *(name.p) = '\0';
1570
1571           mangled = dlang_value (decl, mangled, name.b, type);
1572           string_delete (&name);
1573           break;
1574         }
1575
1576         default:
1577           return NULL;
1578         }
1579     }
1580
1581   return mangled;
1582 }
1583
1584 /* Extract and demangle the template symbol in MANGLED, expected to
1585    be made up of LEN characters, and append it to DECL.
1586    Returns the remaining signature on success or NULL on failure.  */
1587 static const char *
1588 dlang_parse_template (string *decl, const char *mangled, long len)
1589 {
1590   const char *start = mangled;
1591
1592   /* Template instance names have the types and values of its parameters
1593      encoded into it.
1594
1595         TemplateInstanceName:
1596             Number __T LName TemplateArgs Z
1597             Number __U LName TemplateArgs Z
1598                    ^
1599      The start pointer should be at the above location, and LEN should be
1600      the value of the decoded number.
1601    */
1602
1603   /* Template symbol.  */
1604   if (!ISDIGIT (mangled[3]) || mangled[3] == '0')
1605     return NULL;
1606
1607   mangled += 3;
1608
1609   /* Template identifier.  */
1610   mangled = dlang_identifier (decl, mangled, dlang_template_ident);
1611
1612   /* Template arguments.  */
1613   string_append (decl, "!(");
1614   mangled = dlang_template_args (decl, mangled);
1615   string_append (decl, ")");
1616
1617   /* Check for template name length mismatch.  */
1618   if (mangled && (mangled - start) != len)
1619     return NULL;
1620
1621   return mangled;
1622 }
1623
1624 /* Extract and demangle the symbol in MANGLED.  Returns the demangled
1625    signature on success or NULL on failure.  */
1626
1627 char *
1628 dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1629 {
1630   string decl;
1631   char *demangled = NULL;
1632
1633   if (mangled == NULL || *mangled == '\0')
1634     return NULL;
1635
1636   if (strncmp (mangled, "_D", 2) != 0)
1637     return NULL;
1638
1639   string_init (&decl);
1640
1641   if (strcmp (mangled, "_Dmain") == 0)
1642     {
1643       string_append (&decl, "D main");
1644     }
1645   else
1646     {
1647       if (dlang_parse_mangle (&decl, mangled, dlang_top_level) == NULL)
1648         string_delete (&decl);
1649     }
1650
1651   if (string_length (&decl) > 0)
1652     {
1653       string_need (&decl, 1);
1654       *(decl.p) = '\0';
1655       demangled = decl.b;
1656     }
1657
1658   return demangled;
1659 }
1660