]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libiberty/d-demangle.c
1 /* Demangler for the D programming language
2 Copyright 2014, 2015 Free Software Foundation, Inc.
3 Written by Iain Buclaw (ibuclaw@gdcproject.org)
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.
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
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.
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/>. */
29 /* This file exports one function; dlang_demangle.
31 This file imports strtol and strtod for decoding mangled literals. */
37 #include "safe-ctype.h"
39 #include <sys/types.h>
46 extern long strtol (const char *nptr
, char **endptr
, int base
);
47 extern double strtod (const char *nptr
, char **endptr
);
51 #include "libiberty.h"
53 /* A mini string-handling package */
55 typedef struct string
/* Beware: these aren't required to be */
56 { /* '\0' terminated. */
57 char *b
; /* pointer to start of string */
58 char *p
; /* pointer after last character */
59 char *e
; /* pointer after end of allocated space */
63 string_need (string
*s
, int n
)
73 s
->p
= s
->b
= XNEWVEC (char, n
);
76 else if (s
->e
- s
->p
< n
)
81 s
->b
= XRESIZEVEC (char, s
->b
, n
);
88 string_delete (string
*s
)
93 s
->b
= s
->e
= s
->p
= NULL
;
98 string_init (string
*s
)
100 s
->b
= s
->p
= s
->e
= NULL
;
104 string_length (string
*s
)
114 string_setlength (string
*s
, int n
)
116 if (n
- string_length (s
) < 0)
123 string_append (string
*p
, const char *s
)
132 string_appendn (string
*p
, const char *s
, int n
)
143 string_prependn (string
*p
, const char *s
, int n
)
150 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
160 string_prepend (string
*p
, const char *s
)
162 if (s
!= NULL
&& *s
!= '\0')
164 string_prependn (p
, s
, strlen (s
));
168 /* Prototypes for forward referenced functions */
169 static const char *dlang_function_args (string
*, const char *);
171 static const char *dlang_type (string
*, const char *);
173 static const char *dlang_value (string
*, const char *, const char *, char);
175 static const char *dlang_parse_symbol (string
*, const char *);
177 static const char *dlang_parse_tuple (string
*, const char *);
179 static const char *dlang_parse_template (string
*, const char *, long);
182 /* Demangle the calling convention from MANGLED and append it to DECL.
183 Return the remaining string on success or NULL on failure. */
185 dlang_call_convention (string
*decl
, const char *mangled
)
187 if (mangled
== NULL
|| *mangled
== '\0')
197 string_append (decl
, "extern(C) ");
199 case 'W': /* (Windows) */
201 string_append (decl
, "extern(Windows) ");
203 case 'V': /* (Pascal) */
205 string_append (decl
, "extern(Pascal) ");
207 case 'R': /* (C++) */
209 string_append (decl
, "extern(C++) ");
218 /* Extract the type modifiers from MANGLED and append them to DECL.
219 Returns the remaining signature on success or NULL on failure. */
221 dlang_type_modifiers (string
*decl
, const char *mangled
)
223 if (mangled
== NULL
|| *mangled
== '\0')
228 case 'x': /* const */
230 string_append (decl
, " const");
232 case 'y': /* immutable */
234 string_append (decl
, " immutable");
236 case 'O': /* shared */
238 string_append (decl
, " shared");
239 return dlang_type_modifiers (decl
, mangled
);
242 if (*mangled
== 'g') /* wild */
245 string_append (decl
, " inout");
246 return dlang_type_modifiers (decl
, mangled
);
256 /* Demangle the D function attributes from MANGLED and append it to DECL.
257 Return the remaining string on success or NULL on failure. */
259 dlang_attributes (string
*decl
, const char *mangled
)
261 if (mangled
== NULL
|| *mangled
== '\0')
264 while (*mangled
== 'N')
271 string_append (decl
, "pure ");
273 case 'b': /* nothrow */
275 string_append (decl
, "nothrow ");
279 string_append (decl
, "ref ");
281 case 'd': /* @property */
283 string_append (decl
, "@property ");
285 case 'e': /* @trusted */
287 string_append (decl
, "@trusted ");
289 case 'f': /* @safe */
291 string_append (decl
, "@safe ");
295 /* inout parameter is represented as 'Ng'.
296 vector parameter is represented as 'Nh'.
297 If we see this, then we know we're really in the
298 parameter list. Rewind and break. */
301 case 'i': /* @nogc */
303 string_append (decl
, "@nogc ");
312 /* Demangle the function type from MANGLED and append it to DECL.
313 Return the remaining string on success or NULL on failure. */
315 dlang_function_type (string
*decl
, const char *mangled
)
317 string attr
, args
, type
;
318 size_t szattr
, szargs
, sztype
;
320 if (mangled
== NULL
|| *mangled
== '\0')
323 /* The order of the mangled string is:
324 CallConvention FuncAttrs Arguments ArgClose Type
326 The demangled string is re-ordered as:
327 CallConvention Type Arguments FuncAttrs
333 /* Function call convention. */
334 mangled
= dlang_call_convention (decl
, mangled
);
336 /* Function attributes. */
337 mangled
= dlang_attributes (&attr
, mangled
);
338 szattr
= string_length (&attr
);
340 /* Function arguments. */
341 mangled
= dlang_function_args (&args
, mangled
);
342 szargs
= string_length (&args
);
344 /* Function return type. */
345 mangled
= dlang_type (&type
, mangled
);
346 sztype
= string_length (&type
);
348 /* Append to decl in order. */
349 string_appendn (decl
, type
.b
, sztype
);
350 string_append (decl
, "(");
351 string_appendn (decl
, args
.b
, szargs
);
352 string_append (decl
, ") ");
353 string_appendn (decl
, attr
.b
, szattr
);
355 string_delete (&attr
);
356 string_delete (&args
);
357 string_delete (&type
);
361 /* Demangle the argument list from MANGLED and append it to DECL.
362 Return the remaining string on success or NULL on failure. */
364 dlang_function_args (string
*decl
, const char *mangled
)
368 while (mangled
&& *mangled
!= '\0')
372 case 'X': /* (variadic T t...) style. */
374 string_append (decl
, "...");
376 case 'Y': /* (variadic T t, ...) style. */
378 string_append (decl
, ", ...");
380 case 'Z': /* Normal function. */
386 string_append (decl
, ", ");
388 if (*mangled
== 'M') /* scope(T) */
391 string_append (decl
, "scope ");
396 case 'J': /* out(T) */
398 string_append (decl
, "out ");
400 case 'K': /* ref(T) */
402 string_append (decl
, "ref ");
404 case 'L': /* lazy(T) */
406 string_append (decl
, "lazy ");
409 mangled
= dlang_type (decl
, mangled
);
415 /* Demangle the type from MANGLED and append it to DECL.
416 Return the remaining string on success or NULL on failure. */
418 dlang_type (string
*decl
, const char *mangled
)
420 if (mangled
== NULL
|| *mangled
== '\0')
425 case 'O': /* shared(T) */
427 string_append (decl
, "shared(");
428 mangled
= dlang_type (decl
, mangled
);
429 string_append (decl
, ")");
431 case 'x': /* const(T) */
433 string_append (decl
, "const(");
434 mangled
= dlang_type (decl
, mangled
);
435 string_append (decl
, ")");
437 case 'y': /* immutable(T) */
439 string_append (decl
, "immutable(");
440 mangled
= dlang_type (decl
, mangled
);
441 string_append (decl
, ")");
445 if (*mangled
== 'g') /* wild(T) */
448 string_append (decl
, "inout(");
449 mangled
= dlang_type (decl
, mangled
);
450 string_append (decl
, ")");
453 else if (*mangled
== 'h') /* vector(T) */
456 string_append (decl
, "__vector(");
457 mangled
= dlang_type (decl
, mangled
);
458 string_append (decl
, ")");
463 case 'A': /* dynamic array (T[]) */
465 mangled
= dlang_type (decl
, mangled
);
466 string_append (decl
, "[]");
468 case 'G': /* static array (T[N]) */
475 while (ISDIGIT (*mangled
))
480 mangled
= dlang_type (decl
, mangled
);
481 string_append (decl
, "[");
482 string_appendn (decl
, numptr
, num
);
483 string_append (decl
, "]");
486 case 'H': /* associative array (T[T]) */
493 mangled
= dlang_type (&type
, mangled
);
494 sztype
= string_length (&type
);
496 mangled
= dlang_type (decl
, mangled
);
497 string_append (decl
, "[");
498 string_appendn (decl
, type
.b
, sztype
);
499 string_append (decl
, "]");
501 string_delete (&type
);
504 case 'P': /* pointer (T*) */
506 mangled
= dlang_type (decl
, mangled
);
507 string_append (decl
, "*");
509 case 'I': /* ident T */
510 case 'C': /* class T */
511 case 'S': /* struct T */
512 case 'E': /* enum T */
513 case 'T': /* typedef T */
515 return dlang_parse_symbol (decl
, mangled
);
516 case 'D': /* delegate T */
523 mangled
= dlang_type_modifiers (&mods
, mangled
);
524 szmods
= string_length (&mods
);
526 mangled
= dlang_function_type (decl
, mangled
);
527 string_append (decl
, "delegate");
528 string_appendn (decl
, mods
.b
, szmods
);
530 string_delete (&mods
);
533 case 'B': /* tuple T */
535 return dlang_parse_tuple (decl
, mangled
);
538 case 'F': case 'U': case 'W':
540 mangled
= dlang_function_type (decl
, mangled
);
541 string_append (decl
, "function");
547 string_append (decl
, "none");
551 string_append (decl
, "void");
555 string_append (decl
, "byte");
559 string_append (decl
, "ubyte");
563 string_append (decl
, "short");
567 string_append (decl
, "ushort");
571 string_append (decl
, "int");
575 string_append (decl
, "uint");
579 string_append (decl
, "long");
583 string_append (decl
, "ulong");
587 string_append (decl
, "float");
591 string_append (decl
, "double");
595 string_append (decl
, "real");
598 /* Imaginary and Complex types */
601 string_append (decl
, "ifloat");
605 string_append (decl
, "idouble");
609 string_append (decl
, "ireal");
613 string_append (decl
, "cfloat");
617 string_append (decl
, "cdouble");
621 string_append (decl
, "creal");
627 string_append (decl
, "bool");
631 string_append (decl
, "char");
635 string_append (decl
, "wchar");
639 string_append (decl
, "dchar");
642 default: /* unhandled */
647 /* Extract the identifier from MANGLED and append it to DECL.
648 Return the remaining string on success or NULL on failure. */
650 dlang_identifier (string
*decl
, const char *mangled
)
652 if (mangled
== NULL
|| *mangled
== '\0')
655 if (ISDIGIT (*mangled
))
658 long i
= strtol (mangled
, &endptr
, 10);
660 if (endptr
== NULL
|| i
<= 0 || strlen (endptr
) < (size_t) i
)
665 /* May be a template instance. */
666 if (i
>= 5 && strncmp (mangled
, "__T", 3) == 0)
668 /* Template symbol. */
669 if (ISDIGIT (mangled
[3]) && mangled
[3] != '0')
670 return dlang_parse_template (decl
, mangled
, i
);
675 if (strncmp (mangled
, "__ctor", i
) == 0)
677 /* Constructor symbol for a class/struct. */
678 string_append (decl
, "this");
682 else if (strncmp (mangled
, "__dtor", i
) == 0)
684 /* Destructor symbol for a class/struct. */
685 string_append (decl
, "~this");
689 else if (strncmp (mangled
, "__postblit", i
) == 0)
691 /* Postblit symbol for a struct. */
692 string_append (decl
, "this(this)");
696 else if (strncmp (mangled
, "__initZ", i
+1) == 0)
698 /* The static initialiser for a given symbol. */
699 string_append (decl
, "init$");
703 else if (strncmp (mangled
, "__ClassZ", i
+1) == 0)
705 /* The classinfo symbol for a given class. */
706 string_prepend (decl
, "ClassInfo for ");
707 string_setlength (decl
, string_length (decl
) - 1);
711 else if (strncmp (mangled
, "__vtblZ", i
+1) == 0)
713 /* The vtable symbol for a given class. */
714 string_prepend (decl
, "vtable for ");
715 string_setlength (decl
, string_length (decl
) - 1);
719 else if (strncmp (mangled
, "__InterfaceZ", i
+1) == 0)
721 /* The interface symbol for a given class. */
722 string_prepend (decl
, "Interface for ");
723 string_setlength (decl
, string_length (decl
) - 1);
727 else if (strncmp (mangled
, "__ModuleInfoZ", i
+1) == 0)
729 /* The ModuleInfo symbol for a given module. */
730 string_prepend (decl
, "ModuleInfo for ");
731 string_setlength (decl
, string_length (decl
) - 1);
736 string_appendn (decl
, mangled
, i
);
745 /* Extract the integer value from MANGLED and append it to DECL,
746 where TYPE is the type it should be represented as.
747 Return the remaining string on success or NULL on failure. */
749 dlang_parse_integer (string
*decl
, const char *mangled
, char type
)
751 if (type
== 'a' || type
== 'u' || type
== 'w')
753 /* Parse character value. */
758 long val
= strtol (mangled
, &endptr
, 10);
760 if (endptr
== NULL
|| val
< 0)
763 string_append (decl
, "'");
765 if (type
== 'a' && val
>= 0x20 && val
< 0x7F)
767 /* Represent as a character literal. */
769 string_appendn (decl
, &c
, 1);
773 /* Represent as a hexadecimal value. */
777 string_append (decl
, "\\x");
780 case 'u': /* wchar */
781 string_append (decl
, "\\u");
784 case 'w': /* dchar */
785 string_append (decl
, "\\U");
792 int digit
= val
% 16;
795 value
[--pos
] = (char)(digit
+ '0');
797 value
[--pos
] = (char)((digit
- 10) + 'a');
803 for (; width
> 0; width
--)
806 string_appendn (decl
, &(value
[pos
]), 10 - pos
);
808 string_append (decl
, "'");
811 else if (type
== 'b')
813 /* Parse boolean value. */
815 long val
= strtol (mangled
, &endptr
, 10);
817 if (endptr
== NULL
|| val
< 0)
820 string_append (decl
, val
? "true" : "false");
825 /* Parse integer value. */
826 const char *numptr
= mangled
;
829 while (ISDIGIT (*mangled
))
834 string_appendn (decl
, numptr
, num
);
839 case 'h': /* ubyte */
840 case 't': /* ushort */
842 string_append (decl
, "u");
845 string_append (decl
, "L");
847 case 'm': /* ulong */
848 string_append (decl
, "uL");
856 /* Extract the floating-point value from MANGLED and append it to DECL.
857 Return the remaining string on success or NULL on failure. */
859 dlang_parse_real (string
*decl
, const char *mangled
)
866 /* Handle NAN and +-INF. */
867 if (strncmp (mangled
, "NAN", 3) == 0)
869 string_append (decl
, "NaN");
873 else if (strncmp (mangled
, "INF", 3) == 0)
875 string_append (decl
, "Inf");
879 else if (strncmp (mangled
, "NINF", 4) == 0)
881 string_append (decl
, "-Inf");
886 /* Hexadecimal prefix and leading bit. */
893 if (!ISXDIGIT (*mangled
))
898 buffer
[len
++] = *mangled
;
903 while (ISXDIGIT (*mangled
))
905 buffer
[len
++] = *mangled
;
922 while (ISDIGIT (*mangled
))
924 buffer
[len
++] = *mangled
;
928 /* Convert buffer from hexadecimal to floating-point. */
930 value
= strtod (buffer
, &endptr
);
932 if (endptr
== NULL
|| endptr
!= (buffer
+ len
))
935 len
= snprintf (buffer
, sizeof(buffer
), "%#g", value
);
936 string_appendn (decl
, buffer
, len
);
940 /* Convert VAL from an ascii hexdigit to value. */
944 if (val
>= 'a' && val
<= 'f')
945 return (val
- 'a' + 10);
947 if (val
>= 'A' && val
<= 'F')
948 return (val
- 'A' + 10);
950 if (val
>= '0' && val
<= '9')
956 /* Extract the string value from MANGLED and append it to DECL.
957 Return the remaining string on success or NULL on failure. */
959 dlang_parse_string (string
*decl
, const char *mangled
)
961 char type
= *mangled
;
966 len
= strtol (mangled
, &endptr
, 10);
968 if (endptr
== NULL
|| len
< 0)
976 string_append (decl
, "\"");
979 if (ISXDIGIT (mangled
[0]) && ISXDIGIT (mangled
[1]))
981 char a
= ascii2hex (mangled
[0]);
982 char b
= ascii2hex (mangled
[1]);
983 char val
= (a
<< 4) | b
;
985 /* Sanitize white and non-printable characters. */
989 string_append (decl
, " ");
992 string_append (decl
, "\\t");
995 string_append (decl
, "\\n");
998 string_append (decl
, "\\r");
1001 string_append (decl
, "\\f");
1004 string_append (decl
, "\\v");
1009 string_appendn (decl
, &val
, 1);
1012 string_append (decl
, "\\x");
1013 string_appendn (decl
, mangled
, 2);
1022 string_append (decl
, "\"");
1025 string_appendn (decl
, &type
, 1);
1030 /* Extract the static array value from MANGLED and append it to DECL.
1031 Return the remaining string on success or NULL on failure. */
1033 dlang_parse_arrayliteral (string
*decl
, const char *mangled
)
1036 long elements
= strtol (mangled
, &endptr
, 10);
1038 if (endptr
== NULL
|| elements
< 0)
1042 string_append (decl
, "[");
1045 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1047 string_append (decl
, ", ");
1050 string_append (decl
, "]");
1054 /* Extract the associative array value from MANGLED and append it to DECL.
1055 Return the remaining string on success or NULL on failure. */
1057 dlang_parse_assocarray (string
*decl
, const char *mangled
)
1060 long elements
= strtol (mangled
, &endptr
, 10);
1062 if (endptr
== NULL
|| elements
< 0)
1066 string_append (decl
, "[");
1069 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1070 string_append (decl
, ":");
1071 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1074 string_append (decl
, ", ");
1077 string_append (decl
, "]");
1081 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1082 Return the remaining string on success or NULL on failure. */
1084 dlang_parse_structlit (string
*decl
, const char *mangled
, const char *name
)
1087 long args
= strtol (mangled
, &endptr
, 10);
1089 if (endptr
== NULL
|| args
< 0)
1094 string_append (decl
, name
);
1096 string_append (decl
, "(");
1099 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1101 string_append (decl
, ", ");
1104 string_append (decl
, ")");
1108 /* Extract the value from MANGLED and append it to DECL.
1109 Return the remaining string on success or NULL on failure. */
1111 dlang_value (string
*decl
, const char *mangled
, const char *name
, char type
)
1113 if (mangled
== NULL
|| *mangled
== '\0')
1121 string_append (decl
, "null");
1124 /* Integral values. */
1127 string_append (decl
, "-");
1128 mangled
= dlang_parse_integer (decl
, mangled
, type
);
1133 if (*mangled
< '0' || *mangled
> '9')
1136 case '0': case '1': case '2': case '3': case '4':
1137 case '5': case '6': case '7': case '8': case '9':
1138 mangled
= dlang_parse_integer (decl
, mangled
, type
);
1144 mangled
= dlang_parse_real (decl
, mangled
);
1147 /* Complex value. */
1150 mangled
= dlang_parse_real (decl
, mangled
);
1151 string_append (decl
, "+");
1152 if (mangled
== NULL
|| *mangled
!= 'c')
1155 mangled
= dlang_parse_real (decl
, mangled
);
1156 string_append (decl
, "i");
1159 /* String values. */
1160 case 'a': /* UTF8 */
1161 case 'w': /* UTF16 */
1162 case 'd': /* UTF32 */
1163 mangled
= dlang_parse_string (decl
, mangled
);
1170 mangled
= dlang_parse_assocarray (decl
, mangled
);
1172 mangled
= dlang_parse_arrayliteral (decl
, mangled
);
1175 /* Struct values. */
1178 mangled
= dlang_parse_structlit (decl
, mangled
, name
);
1188 /* Extract the type modifiers from MANGLED and return the string
1189 length that it consumes in MANGLED on success or 0 on failure. */
1191 dlang_type_modifier_p (const char *mangled
)
1202 i
= dlang_type_modifier_p (mangled
);
1207 if (*mangled
== 'g')
1210 i
= dlang_type_modifier_p (mangled
);
1218 /* Extract the function calling convention from MANGLED and
1219 return 1 on success or 0 on failure. */
1221 dlang_call_convention_p (const char *mangled
)
1223 /* Prefix for functions needing 'this' */
1224 if (*mangled
== 'M')
1227 /* Also skip over any type modifiers. */
1228 mangled
+= dlang_type_modifier_p (mangled
);
1233 case 'F': case 'U': case 'V':
1242 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1243 Returns the remaining signature on success or NULL on failure. */
1245 dlang_parse_symbol (string
*decl
, const char *mangled
)
1251 string_append (decl
, ".");
1253 mangled
= dlang_identifier (decl
, mangled
);
1255 if (mangled
&& dlang_call_convention_p (mangled
))
1260 /* Skip over 'this' parameter. */
1261 if (*mangled
== 'M')
1264 /* Save the type modifiers for appending at the end. */
1265 string_init (&mods
);
1266 mangled
= dlang_type_modifiers (&mods
, mangled
);
1268 /* Skip over calling convention and attributes in qualified name. */
1269 saved
= string_length (decl
);
1270 mangled
= dlang_call_convention (decl
, mangled
);
1271 mangled
= dlang_attributes (decl
, mangled
);
1272 string_setlength (decl
, saved
);
1274 string_append (decl
, "(");
1275 mangled
= dlang_function_args (decl
, mangled
);
1276 string_append (decl
, ")");
1278 /* Demangle the function return type as a kind of sanity test. */
1279 if (mangled
&& !ISDIGIT (*mangled
))
1281 saved
= string_length (decl
);
1282 mangled
= dlang_type (decl
, mangled
);
1283 string_setlength (decl
, saved
);
1286 /* Add any const/immutable/shared modifier. */
1287 string_appendn (decl
, mods
.b
, string_length (&mods
));
1288 string_delete (&mods
);
1291 while (mangled
&& ISDIGIT (*mangled
));
1296 /* Demangle the tuple from MANGLED and append it to DECL.
1297 Return the remaining string on success or NULL on failure. */
1299 dlang_parse_tuple (string
*decl
, const char *mangled
)
1302 long elements
= strtol (mangled
, &endptr
, 10);
1304 if (endptr
== NULL
|| elements
< 0)
1308 string_append (decl
, "Tuple!(");
1312 mangled
= dlang_type (decl
, mangled
);
1314 string_append (decl
, ", ");
1317 string_append (decl
, ")");
1321 /* Demangle the argument list from MANGLED and append it to DECL.
1322 Return the remaining string on success or NULL on failure. */
1324 dlang_template_args (string
*decl
, const char *mangled
)
1328 while (mangled
&& *mangled
!= '\0')
1332 case 'Z': /* End of parameter list. */
1338 string_append (decl
, ", ");
1342 case 'S': /* Symbol parameter. */
1344 mangled
= dlang_parse_symbol (decl
, mangled
);
1346 case 'T': /* Type parameter. */
1348 mangled
= dlang_type (decl
, mangled
);
1350 case 'V': /* Value parameter. */
1355 /* Peek at the type. */
1359 /* In the few instances where the type is actually desired in
1360 the output, it should precede the value from dlang_value. */
1361 string_init (&name
);
1362 mangled
= dlang_type (&name
, mangled
);
1363 string_need (&name
, 1);
1366 mangled
= dlang_value (decl
, mangled
, name
.b
, type
);
1367 string_delete (&name
);
1379 /* Extract and demangle the template symbol in MANGLED, expected to
1380 be made up of LEN characters, and append it to DECL.
1381 Returns the remaining signature on success or NULL on failure. */
1383 dlang_parse_template (string
*decl
, const char *mangled
, long len
)
1385 const char *start
= mangled
;
1387 /* Template instance names have the types and values of its parameters
1390 TemplateInstanceName:
1391 Number __T LName TemplateArgs Z
1393 The start pointer should be at the above location, and LEN should be
1394 the value of the decoded number.
1396 if (strncmp (mangled
, "__T", 3) != 0)
1401 /* Template identifier. */
1402 mangled
= dlang_identifier (decl
, mangled
);
1404 /* Template arguments. */
1405 string_append (decl
, "!(");
1406 mangled
= dlang_template_args (decl
, mangled
);
1407 string_append (decl
, ")");
1409 /* Check for template name length mismatch. */
1410 if (mangled
&& (mangled
- start
) != len
)
1416 /* Extract and demangle the symbol in MANGLED. Returns the demangled
1417 signature on success or NULL on failure. */
1420 dlang_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
1423 char *demangled
= NULL
;
1425 if (mangled
== NULL
|| *mangled
== '\0')
1428 if (strncmp (mangled
, "_D", 2) != 0)
1431 string_init (&decl
);
1433 if (strcmp (mangled
, "_Dmain") == 0)
1435 string_append (&decl
, "D main");
1441 if (dlang_parse_symbol (&decl
, mangled
) == NULL
)
1442 string_delete (&decl
);
1445 if (string_length (&decl
) > 0)
1447 string_need (&decl
, 1);