d-demangle.c 38 KB

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