d-demangle.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339
  1. /* Demangler for the D programming language
  2. Copyright 2014 Free Software Foundation, Inc.
  3. Written by Iain Buclaw (ibuclaw@gdcproject.org)
  4. This file is part of the libiberty library.
  5. Libiberty is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. In addition to the permissions in the GNU Library General Public
  10. License, the Free Software Foundation gives you unlimited permission
  11. to link the compiled version of this file into combinations with other
  12. programs, and to distribute those combinations without any restriction
  13. coming from the use of this file. (The Library Public License
  14. restrictions do apply in other respects; for example, they cover
  15. modification of the file, and distribution when not linked into a
  16. combined executable.)
  17. Libiberty is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. Library General Public License for more details.
  21. You should have received a copy of the GNU Library General Public
  22. License along with libiberty; see the file COPYING.LIB.
  23. If not, see <http://www.gnu.org/licenses/>. */
  24. /* This file exports one function; dlang_demangle.
  25. This file imports strtol and strtod for decoding mangled literals. */
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include "safe-ctype.h"
  30. #include <sys/types.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #ifdef HAVE_STDLIB_H
  34. #include <stdlib.h>
  35. #else
  36. extern long strtol (const char *nptr, char **endptr, int base);
  37. extern double strtod (const char *nptr, char **endptr);
  38. #endif
  39. #include <demangle.h>
  40. #include "libiberty.h"
  41. /* A mini string-handling package */
  42. typedef struct string /* Beware: these aren't required to be */
  43. { /* '\0' terminated. */
  44. char *b; /* pointer to start of string */
  45. char *p; /* pointer after last character */
  46. char *e; /* pointer after end of allocated space */
  47. } string;
  48. static void
  49. string_need (string *s, int n)
  50. {
  51. int tem;
  52. if (s->b == NULL)
  53. {
  54. if (n < 32)
  55. {
  56. n = 32;
  57. }
  58. s->p = s->b = XNEWVEC (char, n);
  59. s->e = s->b + n;
  60. }
  61. else if (s->e - s->p < n)
  62. {
  63. tem = s->p - s->b;
  64. n += tem;
  65. n *= 2;
  66. s->b = XRESIZEVEC (char, s->b, n);
  67. s->p = s->b + tem;
  68. s->e = s->b + n;
  69. }
  70. }
  71. static void
  72. string_delete (string *s)
  73. {
  74. if (s->b != NULL)
  75. {
  76. XDELETEVEC (s->b);
  77. s->b = s->e = s->p = NULL;
  78. }
  79. }
  80. static void
  81. string_init (string *s)
  82. {
  83. s->b = s->p = s->e = NULL;
  84. }
  85. static int
  86. string_length (string *s)
  87. {
  88. if (s->p == s->b)
  89. {
  90. return 0;
  91. }
  92. return s->p - s->b;
  93. }
  94. static void
  95. string_setlength (string *s, int n)
  96. {
  97. if (n - string_length (s) < 0)
  98. {
  99. s->p = s->b + n;
  100. }
  101. }
  102. static void
  103. string_append (string *p, const char *s)
  104. {
  105. int n = strlen (s);
  106. string_need (p, n);
  107. memcpy (p->p, s, n);
  108. p->p += n;
  109. }
  110. static void
  111. string_appendn (string *p, const char *s, int n)
  112. {
  113. if (n != 0)
  114. {
  115. string_need (p, n);
  116. memcpy (p->p, s, n);
  117. p->p += n;
  118. }
  119. }
  120. static void
  121. string_prependn (string *p, const char *s, int n)
  122. {
  123. char *q;
  124. if (n != 0)
  125. {
  126. string_need (p, n);
  127. for (q = p->p - 1; q >= p->b; q--)
  128. {
  129. q[n] = q[0];
  130. }
  131. memcpy (p->b, s, n);
  132. p->p += n;
  133. }
  134. }
  135. static void
  136. string_prepend (string *p, const char *s)
  137. {
  138. if (s != NULL && *s != '\0')
  139. {
  140. string_prependn (p, s, strlen (s));
  141. }
  142. }
  143. /* Prototypes for forward referenced functions */
  144. static const char *dlang_function_args (string *, const char *);
  145. static const char *dlang_type (string *, const char *);
  146. static const char *dlang_value (string *, const char *, const char *, char);
  147. static const char *dlang_parse_symbol (string *, const char *);
  148. static const char *dlang_parse_tuple (string *, const char *);
  149. static const char *dlang_parse_template (string *, const char *, long);
  150. /* Demangle the calling convention from MANGLED and append it to DECL.
  151. Return the remaining string on success or NULL on failure. */
  152. static const char *
  153. dlang_call_convention (string *decl, const char *mangled)
  154. {
  155. if (mangled == NULL || *mangled == '\0')
  156. return mangled;
  157. switch (*mangled)
  158. {
  159. case 'F': /* (D) */
  160. mangled++;
  161. break;
  162. case 'U': /* (C) */
  163. mangled++;
  164. string_append (decl, "extern(C) ");
  165. break;
  166. case 'W': /* (Windows) */
  167. mangled++;
  168. string_append (decl, "extern(Windows) ");
  169. break;
  170. case 'V': /* (Pascal) */
  171. mangled++;
  172. string_append (decl, "extern(Pascal) ");
  173. break;
  174. case 'R': /* (C++) */
  175. mangled++;
  176. string_append (decl, "extern(C++) ");
  177. break;
  178. default:
  179. return NULL;
  180. }
  181. return mangled;
  182. }
  183. /* Demangle the D function attributes from MANGLED and append it to DECL.
  184. Return the remaining string on success or NULL on failure. */
  185. static const char *
  186. dlang_attributes (string *decl, const char *mangled)
  187. {
  188. if (mangled == NULL || *mangled == '\0')
  189. return mangled;
  190. while (*mangled == 'N')
  191. {
  192. mangled++;
  193. switch (*mangled)
  194. {
  195. case 'a': /* pure */
  196. mangled++;
  197. string_append (decl, "pure ");
  198. continue;
  199. case 'b': /* nothrow */
  200. mangled++;
  201. string_append (decl, "nothrow ");
  202. continue;
  203. case 'c': /* ref */
  204. mangled++;
  205. string_append (decl, "ref ");
  206. continue;
  207. case 'd': /* @property */
  208. mangled++;
  209. string_append (decl, "@property ");
  210. continue;
  211. case 'e': /* @trusted */
  212. mangled++;
  213. string_append (decl, "@trusted ");
  214. continue;
  215. case 'f': /* @safe */
  216. mangled++;
  217. string_append (decl, "@safe ");
  218. continue;
  219. case 'g':
  220. case 'h':
  221. /* inout parameter is represented as 'Ng'.
  222. vector parameter is represented as 'Nh'.
  223. If we see this, then we know we're really in the
  224. parameter list. Rewind and break. */
  225. mangled--;
  226. break;
  227. case 'i': /* @nogc */
  228. mangled++;
  229. string_append (decl, "@nogc ");
  230. continue;
  231. }
  232. break;
  233. }
  234. return mangled;
  235. }
  236. /* Demangle the function type from MANGLED and append it to DECL.
  237. Return the remaining string on success or NULL on failure. */
  238. static const char *
  239. dlang_function_type (string *decl, const char *mangled)
  240. {
  241. string attr, args, type;
  242. size_t szattr, szargs, sztype;
  243. if (mangled == NULL || *mangled == '\0')
  244. return mangled;
  245. /* The order of the mangled string is:
  246. CallConvention FuncAttrs Arguments ArgClose Type
  247. The demangled string is re-ordered as:
  248. CallConvention Type Arguments FuncAttrs
  249. */
  250. string_init (&attr);
  251. string_init (&args);
  252. string_init (&type);
  253. /* Function call convention. */
  254. mangled = dlang_call_convention (decl, mangled);
  255. /* Function attributes. */
  256. mangled = dlang_attributes (&attr, mangled);
  257. szattr = string_length (&attr);
  258. /* Function arguments. */
  259. mangled = dlang_function_args (&args, mangled);
  260. szargs = string_length (&args);
  261. /* Function return type. */
  262. mangled = dlang_type (&type, mangled);
  263. sztype = string_length (&type);
  264. /* Append to decl in order. */
  265. string_appendn (decl, type.b, sztype);
  266. string_append (decl, "(");
  267. string_appendn (decl, args.b, szargs);
  268. string_append (decl, ") ");
  269. string_appendn (decl, attr.b, szattr);
  270. string_delete (&attr);
  271. string_delete (&args);
  272. string_delete (&type);
  273. return mangled;
  274. }
  275. /* Demangle the argument list from MANGLED and append it to DECL.
  276. Return the remaining string on success or NULL on failure. */
  277. static const char *
  278. dlang_function_args (string *decl, const char *mangled)
  279. {
  280. size_t n = 0;
  281. while (mangled && *mangled != '\0')
  282. {
  283. switch (*mangled)
  284. {
  285. case 'X': /* (variadic T t...) style. */
  286. mangled++;
  287. string_append (decl, "...");
  288. return mangled;
  289. case 'Y': /* (variadic T t, ...) style. */
  290. mangled++;
  291. string_append (decl, ", ...");
  292. return mangled;
  293. case 'Z': /* Normal function. */
  294. mangled++;
  295. return mangled;
  296. }
  297. if (n++)
  298. string_append (decl, ", ");
  299. if (*mangled == 'M') /* scope(T) */
  300. {
  301. mangled++;
  302. string_append (decl, "scope ");
  303. }
  304. switch (*mangled)
  305. {
  306. case 'J': /* out(T) */
  307. mangled++;
  308. string_append (decl, "out ");
  309. break;
  310. case 'K': /* ref(T) */
  311. mangled++;
  312. string_append (decl, "ref ");
  313. break;
  314. case 'L': /* lazy(T) */
  315. mangled++;
  316. string_append (decl, "lazy ");
  317. break;
  318. }
  319. mangled = dlang_type (decl, mangled);
  320. }
  321. return mangled;
  322. }
  323. /* Demangle the type from MANGLED and append it to DECL.
  324. Return the remaining string on success or NULL on failure. */
  325. static const char *
  326. dlang_type (string *decl, const char *mangled)
  327. {
  328. if (mangled == NULL || *mangled == '\0')
  329. return mangled;
  330. switch (*mangled)
  331. {
  332. case 'O': /* shared(T) */
  333. mangled++;
  334. string_append (decl, "shared(");
  335. mangled = dlang_type (decl, mangled);
  336. string_append (decl, ")");
  337. return mangled;
  338. case 'x': /* const(T) */
  339. mangled++;
  340. string_append (decl, "const(");
  341. mangled = dlang_type (decl, mangled);
  342. string_append (decl, ")");
  343. return mangled;
  344. case 'y': /* immutable(T) */
  345. mangled++;
  346. string_append (decl, "immutable(");
  347. mangled = dlang_type (decl, mangled);
  348. string_append (decl, ")");
  349. return mangled;
  350. case 'N':
  351. mangled++;
  352. if (*mangled == 'g') /* wild(T) */
  353. {
  354. mangled++;
  355. string_append (decl, "inout(");
  356. mangled = dlang_type (decl, mangled);
  357. string_append (decl, ")");
  358. return mangled;
  359. }
  360. else if (*mangled == 'h') /* vector(T) */
  361. {
  362. mangled++;
  363. string_append (decl, "__vector(");
  364. mangled = dlang_type (decl, mangled);
  365. string_append (decl, ")");
  366. return mangled;
  367. }
  368. else
  369. return NULL;
  370. case 'A': /* dynamic array (T[]) */
  371. mangled++;
  372. mangled = dlang_type (decl, mangled);
  373. string_append (decl, "[]");
  374. return mangled;
  375. case 'G': /* static array (T[N]) */
  376. {
  377. const char *numptr;
  378. size_t num = 0;
  379. mangled++;
  380. numptr = mangled;
  381. while (ISDIGIT (*mangled))
  382. {
  383. num++;
  384. mangled++;
  385. }
  386. mangled = dlang_type (decl, mangled);
  387. string_append (decl, "[");
  388. string_appendn (decl, numptr, num);
  389. string_append (decl, "]");
  390. return mangled;
  391. }
  392. case 'H': /* associative array (T[T]) */
  393. {
  394. string type;
  395. size_t sztype;
  396. mangled++;
  397. string_init (&type);
  398. mangled = dlang_type (&type, mangled);
  399. sztype = string_length (&type);
  400. mangled = dlang_type (decl, mangled);
  401. string_append (decl, "[");
  402. string_appendn (decl, type.b, sztype);
  403. string_append (decl, "]");
  404. string_delete (&type);
  405. return mangled;
  406. }
  407. case 'P': /* pointer (T*) */
  408. mangled++;
  409. mangled = dlang_type (decl, mangled);
  410. string_append (decl, "*");
  411. return mangled;
  412. case 'I': /* ident T */
  413. case 'C': /* class T */
  414. case 'S': /* struct T */
  415. case 'E': /* enum T */
  416. case 'T': /* typedef T */
  417. mangled++;
  418. return dlang_parse_symbol (decl, mangled);
  419. case 'D': /* delegate T */
  420. mangled++;
  421. mangled = dlang_function_type (decl, mangled);
  422. string_append (decl, "delegate");
  423. return mangled;
  424. case 'B': /* tuple T */
  425. mangled++;
  426. return dlang_parse_tuple (decl, mangled);
  427. /* Function types */
  428. case 'F': case 'U': case 'W':
  429. case 'V': case 'R':
  430. mangled = dlang_function_type (decl, mangled);
  431. string_append (decl, "function");
  432. return mangled;
  433. /* Basic types */
  434. case 'n':
  435. mangled++;
  436. string_append (decl, "none");
  437. return mangled;
  438. case 'v':
  439. mangled++;
  440. string_append (decl, "void");
  441. return mangled;
  442. case 'g':
  443. mangled++;
  444. string_append (decl, "byte");
  445. return mangled;
  446. case 'h':
  447. mangled++;
  448. string_append (decl, "ubyte");
  449. return mangled;
  450. case 's':
  451. mangled++;
  452. string_append (decl, "short");
  453. return mangled;
  454. case 't':
  455. mangled++;
  456. string_append (decl, "ushort");
  457. return mangled;
  458. case 'i':
  459. mangled++;
  460. string_append (decl, "int");
  461. return mangled;
  462. case 'k':
  463. mangled++;
  464. string_append (decl, "uint");
  465. return mangled;
  466. case 'l':
  467. mangled++;
  468. string_append (decl, "long");
  469. return mangled;
  470. case 'm':
  471. mangled++;
  472. string_append (decl, "ulong");
  473. return mangled;
  474. case 'f':
  475. mangled++;
  476. string_append (decl, "float");
  477. return mangled;
  478. case 'd':
  479. mangled++;
  480. string_append (decl, "double");
  481. return mangled;
  482. case 'e':
  483. mangled++;
  484. string_append (decl, "real");
  485. return mangled;
  486. /* Imaginary and Complex types */
  487. case 'o':
  488. mangled++;
  489. string_append (decl, "ifloat");
  490. return mangled;
  491. case 'p':
  492. mangled++;
  493. string_append (decl, "idouble");
  494. return mangled;
  495. case 'j':
  496. mangled++;
  497. string_append (decl, "ireal");
  498. return mangled;
  499. case 'q':
  500. mangled++;
  501. string_append (decl, "cfloat");
  502. return mangled;
  503. case 'r':
  504. mangled++;
  505. string_append (decl, "cdouble");
  506. return mangled;
  507. case 'c':
  508. mangled++;
  509. string_append (decl, "creal");
  510. return mangled;
  511. /* Other types */
  512. case 'b':
  513. mangled++;
  514. string_append (decl, "bool");
  515. return mangled;
  516. case 'a':
  517. mangled++;
  518. string_append (decl, "char");
  519. return mangled;
  520. case 'u':
  521. mangled++;
  522. string_append (decl, "wchar");
  523. return mangled;
  524. case 'w':
  525. mangled++;
  526. string_append (decl, "dchar");
  527. return mangled;
  528. default: /* unhandled */
  529. return NULL;
  530. }
  531. }
  532. /* Extract the identifier from MANGLED and append it to DECL.
  533. Return the remaining string on success or NULL on failure. */
  534. static const char *
  535. dlang_identifier (string *decl, const char *mangled)
  536. {
  537. if (mangled == NULL || *mangled == '\0')
  538. return mangled;
  539. if (ISDIGIT (*mangled))
  540. {
  541. char *endptr;
  542. long i = strtol (mangled, &endptr, 10);
  543. if (endptr == NULL || i <= 0 || strlen (endptr) < (size_t) i)
  544. return NULL;
  545. mangled = endptr;
  546. /* May be a template instance. */
  547. if (i >= 5 && strncmp (mangled, "__T", 3) == 0)
  548. {
  549. /* Template symbol. */
  550. if (ISDIGIT (mangled[3]) && mangled[3] != '0')
  551. return dlang_parse_template (decl, mangled, i);
  552. return NULL;
  553. }
  554. if (strncmp (mangled, "__ctor", i) == 0)
  555. {
  556. /* Constructor symbol for a class/struct. */
  557. string_append (decl, "this");
  558. mangled += i;
  559. return mangled;
  560. }
  561. else if (strncmp (mangled, "__dtor", i) == 0)
  562. {
  563. /* Destructor symbol for a class/struct. */
  564. string_append (decl, "~this");
  565. mangled += i;
  566. return mangled;
  567. }
  568. else if (strncmp (mangled, "__postblit", i) == 0)
  569. {
  570. /* Postblit symbol for a struct. */
  571. string_append (decl, "this(this)");
  572. mangled += i;
  573. return mangled;
  574. }
  575. else if (strncmp (mangled, "__initZ", i+1) == 0)
  576. {
  577. /* The static initialiser for a given symbol. */
  578. string_append (decl, "init$");
  579. mangled += i + 1;
  580. return mangled;
  581. }
  582. else if (strncmp (mangled, "__ClassZ", i+1) == 0)
  583. {
  584. /* The classinfo symbol for a given class. */
  585. string_prepend (decl, "ClassInfo for ");
  586. string_setlength (decl, string_length (decl) - 1);
  587. mangled += i + 1;
  588. return mangled;
  589. }
  590. else if (strncmp (mangled, "__vtblZ", i+1) == 0)
  591. {
  592. /* The vtable symbol for a given class. */
  593. string_prepend (decl, "vtable for ");
  594. string_setlength (decl, string_length (decl) - 1);
  595. mangled += i + 1;
  596. return mangled;
  597. }
  598. else if (strncmp (mangled, "__InterfaceZ", i+1) == 0)
  599. {
  600. /* The interface symbol for a given class. */
  601. string_prepend (decl, "Interface for ");
  602. string_setlength (decl, string_length (decl) - 1);
  603. mangled += i + 1;
  604. return mangled;
  605. }
  606. else if (strncmp (mangled, "__ModuleInfoZ", i+1) == 0)
  607. {
  608. /* The ModuleInfo symbol for a given module. */
  609. string_prepend (decl, "ModuleInfo for ");
  610. string_setlength (decl, string_length (decl) - 1);
  611. mangled += i + 1;
  612. return mangled;
  613. }
  614. string_appendn (decl, mangled, i);
  615. mangled += i;
  616. }
  617. else
  618. return NULL;
  619. return mangled;
  620. }
  621. /* Extract the integer value from MANGLED and append it to DECL,
  622. where TYPE is the type it should be represented as.
  623. Return the remaining string on success or NULL on failure. */
  624. static const char *
  625. dlang_parse_integer (string *decl, const char *mangled, char type)
  626. {
  627. if (type == 'a' || type == 'u' || type == 'w')
  628. {
  629. /* Parse character value. */
  630. char value[10];
  631. int pos = 10;
  632. int width = 0;
  633. char *endptr;
  634. long val = strtol (mangled, &endptr, 10);
  635. if (endptr == NULL || val < 0)
  636. return NULL;
  637. string_append (decl, "'");
  638. if (type == 'a' && val >= 0x20 && val < 0x7F)
  639. {
  640. /* Represent as a character literal. */
  641. char c = (char) val;
  642. string_appendn (decl, &c, 1);
  643. }
  644. else
  645. {
  646. /* Represent as a hexadecimal value. */
  647. switch (type)
  648. {
  649. case 'a': /* char */
  650. string_append (decl, "\\x");
  651. width = 2;
  652. break;
  653. case 'u': /* wchar */
  654. string_append (decl, "\\u");
  655. width = 4;
  656. break;
  657. case 'w': /* dchar */
  658. string_append (decl, "\\U");
  659. width = 8;
  660. break;
  661. }
  662. while (val > 0)
  663. {
  664. int digit = val % 16;
  665. if (digit < 10)
  666. value[--pos] = (char)(digit + '0');
  667. else
  668. value[--pos] = (char)((digit - 10) + 'a');
  669. val /= 16;
  670. width--;
  671. }
  672. for (; width > 0; width--)
  673. value[--pos] = '0';
  674. string_appendn (decl, &(value[pos]), 10 - pos);
  675. }
  676. string_append (decl, "'");
  677. mangled = endptr;
  678. }
  679. else if (type == 'b')
  680. {
  681. /* Parse boolean value. */
  682. char *endptr;
  683. long val = strtol (mangled, &endptr, 10);
  684. if (endptr == NULL || val < 0)
  685. return NULL;
  686. string_append (decl, val ? "true" : "false");
  687. mangled = endptr;
  688. }
  689. else
  690. {
  691. /* Parse integer value. */
  692. const char *numptr = mangled;
  693. size_t num = 0;
  694. while (ISDIGIT (*mangled))
  695. {
  696. num++;
  697. mangled++;
  698. }
  699. string_appendn (decl, numptr, num);
  700. /* Append suffix. */
  701. switch (type)
  702. {
  703. case 'h': /* ubyte */
  704. case 't': /* ushort */
  705. case 'k': /* uint */
  706. string_append (decl, "u");
  707. break;
  708. case 'l': /* long */
  709. string_append (decl, "L");
  710. break;
  711. case 'm': /* ulong */
  712. string_append (decl, "uL");
  713. break;
  714. }
  715. }
  716. return mangled;
  717. }
  718. /* Extract the floating-point value from MANGLED and append it to DECL.
  719. Return the remaining string on success or NULL on failure. */
  720. static const char *
  721. dlang_parse_real (string *decl, const char *mangled)
  722. {
  723. char buffer[64];
  724. int len = 0;
  725. double value;
  726. char *endptr;
  727. /* Handle NAN and +-INF. */
  728. if (strncmp (mangled, "NAN", 3) == 0)
  729. {
  730. string_append (decl, "NaN");
  731. mangled += 3;
  732. return mangled;
  733. }
  734. else if (strncmp (mangled, "INF", 3) == 0)
  735. {
  736. string_append (decl, "Inf");
  737. mangled += 3;
  738. return mangled;
  739. }
  740. else if (strncmp (mangled, "NINF", 4) == 0)
  741. {
  742. string_append (decl, "-Inf");
  743. mangled += 4;
  744. return mangled;
  745. }
  746. /* Hexadecimal prefix and leading bit. */
  747. if (*mangled == 'N')
  748. {
  749. buffer[len++] = '-';
  750. mangled++;
  751. }
  752. if (!ISXDIGIT (*mangled))
  753. return NULL;
  754. buffer[len++] = '0';
  755. buffer[len++] = 'x';
  756. buffer[len++] = *mangled;
  757. buffer[len++] = '.';
  758. mangled++;
  759. /* Significand. */
  760. while (ISXDIGIT (*mangled))
  761. {
  762. buffer[len++] = *mangled;
  763. mangled++;
  764. }
  765. /* Exponent. */
  766. if (*mangled != 'P')
  767. return NULL;
  768. buffer[len++] = 'p';
  769. mangled++;
  770. if (*mangled == 'N')
  771. {
  772. buffer[len++] = '-';
  773. mangled++;
  774. }
  775. while (ISDIGIT (*mangled))
  776. {
  777. buffer[len++] = *mangled;
  778. mangled++;
  779. }
  780. /* Convert buffer from hexadecimal to floating-point. */
  781. buffer[len] = '\0';
  782. value = strtod (buffer, &endptr);
  783. if (endptr == NULL || endptr != (buffer + len))
  784. return NULL;
  785. len = snprintf (buffer, sizeof(buffer), "%#g", value);
  786. string_appendn (decl, buffer, len);
  787. return mangled;
  788. }
  789. /* Convert VAL from an ascii hexdigit to value. */
  790. static char
  791. ascii2hex (char val)
  792. {
  793. if (val >= 'a' && val <= 'f')
  794. return (val - 'a' + 10);
  795. if (val >= 'A' && val <= 'F')
  796. return (val - 'A' + 10);
  797. if (val >= '0' && val <= '9')
  798. return (val - '0');
  799. return 0;
  800. }
  801. /* Extract the string value from MANGLED and append it to DECL.
  802. Return the remaining string on success or NULL on failure. */
  803. static const char *
  804. dlang_parse_string (string *decl, const char *mangled)
  805. {
  806. char type = *mangled;
  807. char *endptr;
  808. long len;
  809. mangled++;
  810. len = strtol (mangled, &endptr, 10);
  811. if (endptr == NULL || len < 0)
  812. return NULL;
  813. mangled = endptr;
  814. if (*mangled != '_')
  815. return NULL;
  816. mangled++;
  817. string_append (decl, "\"");
  818. while (len--)
  819. {
  820. if (ISXDIGIT (mangled[0]) && ISXDIGIT (mangled[1]))
  821. {
  822. char a = ascii2hex (mangled[0]);
  823. char b = ascii2hex (mangled[1]);
  824. char val = (a << 4) | b;
  825. string_appendn (decl, &val, 1);
  826. }
  827. else
  828. return NULL;
  829. mangled += 2;
  830. }
  831. string_append (decl, "\"");
  832. if (type != 'a')
  833. string_appendn (decl, &type, 1);
  834. return mangled;
  835. }
  836. /* Extract the static array value from MANGLED and append it to DECL.
  837. Return the remaining string on success or NULL on failure. */
  838. static const char *
  839. dlang_parse_arrayliteral (string *decl, const char *mangled)
  840. {
  841. char *endptr;
  842. long elements = strtol (mangled, &endptr, 10);
  843. if (endptr == NULL || elements < 0)
  844. return NULL;
  845. mangled = endptr;
  846. string_append (decl, "[");
  847. while (elements--)
  848. {
  849. mangled = dlang_value (decl, mangled, NULL, '\0');
  850. if (elements != 0)
  851. string_append (decl, ", ");
  852. }
  853. string_append (decl, "]");
  854. return mangled;
  855. }
  856. /* Extract the associative array value from MANGLED and append it to DECL.
  857. Return the remaining string on success or NULL on failure. */
  858. static const char *
  859. dlang_parse_assocarray (string *decl, const char *mangled)
  860. {
  861. char *endptr;
  862. long elements = strtol (mangled, &endptr, 10);
  863. if (endptr == NULL || elements < 0)
  864. return NULL;
  865. mangled = endptr;
  866. string_append (decl, "[");
  867. while (elements--)
  868. {
  869. mangled = dlang_value (decl, mangled, NULL, '\0');
  870. string_append (decl, ":");
  871. mangled = dlang_value (decl, mangled, NULL, '\0');
  872. if (elements != 0)
  873. string_append (decl, ", ");
  874. }
  875. string_append (decl, "]");
  876. return mangled;
  877. }
  878. /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
  879. Return the remaining string on success or NULL on failure. */
  880. static const char *
  881. dlang_parse_structlit (string *decl, const char *mangled, const char *name)
  882. {
  883. char *endptr;
  884. long args = strtol (mangled, &endptr, 10);
  885. if (endptr == NULL || args < 0)
  886. return NULL;
  887. mangled = endptr;
  888. if (name != NULL)
  889. string_append (decl, name);
  890. string_append (decl, "(");
  891. while (args--)
  892. {
  893. mangled = dlang_value (decl, mangled, NULL, '\0');
  894. if (args != 0)
  895. string_append (decl, ", ");
  896. }
  897. string_append (decl, ")");
  898. return mangled;
  899. }
  900. /* Extract the value from MANGLED and append it to DECL.
  901. Return the remaining string on success or NULL on failure. */
  902. static const char *
  903. dlang_value (string *decl, const char *mangled, const char *name, char type)
  904. {
  905. if (mangled == NULL || *mangled == '\0')
  906. return mangled;
  907. switch (*mangled)
  908. {
  909. /* Null value. */
  910. case 'n':
  911. mangled++;
  912. string_append (decl, "null");
  913. break;
  914. /* Integral values. */
  915. case 'N':
  916. mangled++;
  917. string_append (decl, "-");
  918. mangled = dlang_parse_integer (decl, mangled, type);
  919. break;
  920. case 'i':
  921. mangled++;
  922. if (*mangled < '0' || *mangled > '9')
  923. return NULL;
  924. /* Fall through */
  925. case '0': case '1': case '2': case '3': case '4':
  926. case '5': case '6': case '7': case '8': case '9':
  927. mangled = dlang_parse_integer (decl, mangled, type);
  928. break;
  929. /* Real value. */
  930. case 'e':
  931. mangled++;
  932. mangled = dlang_parse_real (decl, mangled);
  933. break;
  934. /* Complex value. */
  935. case 'c':
  936. mangled++;
  937. mangled = dlang_parse_real (decl, mangled);
  938. string_append (decl, "+");
  939. if (mangled == NULL || *mangled != 'c')
  940. return NULL;
  941. mangled++;
  942. mangled = dlang_parse_real (decl, mangled);
  943. string_append (decl, "i");
  944. break;
  945. /* String values. */
  946. case 'a': /* UTF8 */
  947. case 'w': /* UTF16 */
  948. case 'd': /* UTF32 */
  949. mangled = dlang_parse_string (decl, mangled);
  950. break;
  951. /* Array values. */
  952. case 'A':
  953. mangled++;
  954. if (type == 'H')
  955. mangled = dlang_parse_assocarray (decl, mangled);
  956. else
  957. mangled = dlang_parse_arrayliteral (decl, mangled);
  958. break;
  959. /* Struct values. */
  960. case 'S':
  961. mangled++;
  962. mangled = dlang_parse_structlit (decl, mangled, name);
  963. break;
  964. default:
  965. return NULL;
  966. }
  967. return mangled;
  968. }
  969. static int
  970. dlang_call_convention_p (const char *mangled)
  971. {
  972. size_t i;
  973. switch (*mangled)
  974. {
  975. case 'F': case 'U': case 'V':
  976. case 'W': case 'R':
  977. return 1;
  978. case 'M': /* Prefix for functions needing 'this' */
  979. i = 1;
  980. if (mangled[i] == 'x')
  981. i++;
  982. switch (mangled[i])
  983. {
  984. case 'F': case 'U': case 'V':
  985. case 'W': case 'R':
  986. return 1;
  987. }
  988. default:
  989. return 0;
  990. }
  991. }
  992. /* Extract and demangle the symbol in MANGLED and append it to DECL.
  993. Returns the remaining signature on success or NULL on failure. */
  994. static const char *
  995. dlang_parse_symbol (string *decl, const char *mangled)
  996. {
  997. size_t n = 0;
  998. do
  999. {
  1000. if (n++)
  1001. string_append (decl, ".");
  1002. mangled = dlang_identifier (decl, mangled);
  1003. if (mangled && dlang_call_convention_p (mangled))
  1004. {
  1005. int saved;
  1006. /* Skip over 'this' parameter. */
  1007. if (*mangled == 'M')
  1008. mangled += (mangled[1] == 'x') ? 2 : 1;
  1009. /* Skip over calling convention and attributes in qualified name. */
  1010. saved = string_length (decl);
  1011. mangled = dlang_call_convention (decl, mangled);
  1012. mangled = dlang_attributes (decl, mangled);
  1013. string_setlength (decl, saved);
  1014. string_append (decl, "(");
  1015. mangled = dlang_function_args (decl, mangled);
  1016. string_append (decl, ")");
  1017. /* Demangle the function return type as a kind of sanity test. */
  1018. if (mangled && !ISDIGIT (*mangled))
  1019. {
  1020. saved = string_length (decl);
  1021. mangled = dlang_type (decl, mangled);
  1022. string_setlength (decl, saved);
  1023. }
  1024. }
  1025. }
  1026. while (mangled && ISDIGIT (*mangled));
  1027. return mangled;
  1028. }
  1029. /* Demangle the tuple from MANGLED and append it to DECL.
  1030. Return the remaining string on success or NULL on failure. */
  1031. static const char *
  1032. dlang_parse_tuple (string *decl, const char *mangled)
  1033. {
  1034. char *endptr;
  1035. long elements = strtol (mangled, &endptr, 10);
  1036. if (endptr == NULL || elements < 0)
  1037. return NULL;
  1038. mangled = endptr;
  1039. string_append (decl, "Tuple!(");
  1040. while (elements--)
  1041. {
  1042. mangled = dlang_type (decl, mangled);
  1043. if (elements != 0)
  1044. string_append (decl, ", ");
  1045. }
  1046. string_append (decl, ")");
  1047. return mangled;
  1048. }
  1049. /* Demangle the argument list from MANGLED and append it to DECL.
  1050. Return the remaining string on success or NULL on failure. */
  1051. static const char *
  1052. dlang_template_args (string *decl, const char *mangled)
  1053. {
  1054. size_t n = 0;
  1055. while (mangled && *mangled != '\0')
  1056. {
  1057. switch (*mangled)
  1058. {
  1059. case 'Z': /* End of parameter list. */
  1060. mangled++;
  1061. return mangled;
  1062. }
  1063. if (n++)
  1064. string_append (decl, ", ");
  1065. switch (*mangled)
  1066. {
  1067. case 'S': /* Symbol parameter. */
  1068. mangled++;
  1069. mangled = dlang_parse_symbol (decl, mangled);
  1070. break;
  1071. case 'T': /* Type parameter. */
  1072. mangled++;
  1073. mangled = dlang_type (decl, mangled);
  1074. break;
  1075. case 'V': /* Value parameter. */
  1076. {
  1077. string name;
  1078. char type;
  1079. /* Peek at the type. */
  1080. mangled++;
  1081. type = *mangled;
  1082. /* In the few instances where the type is actually desired in
  1083. the output, it should precede the value from dlang_value. */
  1084. string_init (&name);
  1085. mangled = dlang_type (&name, mangled);
  1086. string_need (&name, 1);
  1087. *(name.p) = '\0';
  1088. mangled = dlang_value (decl, mangled, name.b, type);
  1089. string_delete (&name);
  1090. break;
  1091. }
  1092. default:
  1093. return NULL;
  1094. }
  1095. }
  1096. return mangled;
  1097. }
  1098. /* Extract and demangle the template symbol in MANGLED, expected to
  1099. be made up of LEN characters, and append it to DECL.
  1100. Returns the remaining signature on success or NULL on failure. */
  1101. static const char *
  1102. dlang_parse_template (string *decl, const char *mangled, long len)
  1103. {
  1104. const char *start = mangled;
  1105. /* Template instance names have the types and values of its parameters
  1106. encoded into it.
  1107. TemplateInstanceName:
  1108. Number __T LName TemplateArgs Z
  1109. ^
  1110. The start pointer should be at the above location, and LEN should be
  1111. the value of the decoded number.
  1112. */
  1113. if (strncmp (mangled, "__T", 3) != 0)
  1114. return NULL;
  1115. mangled += 3;
  1116. /* Template identifier. */
  1117. mangled = dlang_identifier (decl, mangled);
  1118. /* Template arguments. */
  1119. string_append (decl, "!(");
  1120. mangled = dlang_template_args (decl, mangled);
  1121. string_append (decl, ")");
  1122. /* Check for template name length mismatch. */
  1123. if (mangled && (mangled - start) != len)
  1124. return NULL;
  1125. return mangled;
  1126. }
  1127. /* Extract and demangle the symbol in MANGLED. Returns the demangled
  1128. signature on success or NULL on failure. */
  1129. char *
  1130. dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
  1131. {
  1132. string decl;
  1133. char *demangled = NULL;
  1134. if (mangled == NULL || *mangled == '\0')
  1135. return NULL;
  1136. if (strncmp (mangled, "_D", 2) != 0)
  1137. return NULL;
  1138. string_init (&decl);
  1139. if (strcmp (mangled, "_Dmain") == 0)
  1140. {
  1141. string_append (&decl, "D main");
  1142. }
  1143. else
  1144. {
  1145. mangled += 2;
  1146. if (dlang_parse_symbol (&decl, mangled) == NULL)
  1147. string_delete (&decl);
  1148. }
  1149. if (string_length (&decl) > 0)
  1150. {
  1151. string_need (&decl, 1);
  1152. *(decl.p) = '\0';
  1153. demangled = decl.b;
  1154. }
  1155. return demangled;
  1156. }