msmangle.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. /*
  2. * Demangle VC++ symbols into C function prototypes
  3. *
  4. * Copyright 2000 Jon Griffiths
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include "config.h"
  21. #include "wine/port.h"
  22. #include "winedump.h"
  23. /* Type for parsing mangled types */
  24. typedef struct _compound_type
  25. {
  26. char dest_type;
  27. int flags;
  28. BOOL have_qualifiers;
  29. char *expression;
  30. } compound_type;
  31. /* Initialise a compound type structure */
  32. #define INIT_CT(ct) do { memset (&ct, 0, sizeof (ct)); } while (0)
  33. /* free the memory used by a compound structure */
  34. #define FREE_CT(ct) free (ct.expression)
  35. /* Flags for data types */
  36. #define DATA_VTABLE 0x1
  37. /* Internal functions */
  38. static char *demangle_datatype (char **str, compound_type *ct,
  39. parsed_symbol* sym);
  40. static char *get_constraints_convention_1 (char **str, compound_type *ct);
  41. static char *get_constraints_convention_2 (char **str, compound_type *ct);
  42. static char *get_type_string (const char c, const int constraints);
  43. static int get_type_constant (const char c, const int constraints);
  44. static char *get_pointer_type_string (compound_type *ct,
  45. const char *expression);
  46. /*******************************************************************
  47. * demangle_symbol
  48. *
  49. * Demangle a C++ linker symbol into a C prototype
  50. */
  51. BOOL symbol_demangle (parsed_symbol *sym)
  52. {
  53. compound_type ct;
  54. BOOL is_static = FALSE;
  55. int is_const = 0;
  56. char *function_name = NULL;
  57. char *class_name = NULL;
  58. char *name;
  59. const char *const_status;
  60. static unsigned int hash = 0; /* In case of overloaded functions */
  61. unsigned int data_flags = 0;
  62. assert (globals.do_code);
  63. assert (sym && sym->symbol);
  64. hash++;
  65. /* MS mangled names always begin with '?' */
  66. name = sym->symbol;
  67. if (*name++ != '?')
  68. return FALSE;
  69. if (VERBOSE)
  70. puts ("Attempting to demangle symbol");
  71. /* Then function name or operator code */
  72. if (*name == '?')
  73. {
  74. /* C++ operator code (one character, or two if the first is '_') */
  75. switch (*++name)
  76. {
  77. case '0': function_name = strdup ("ctor"); break;
  78. case '1': function_name = strdup ("dtor"); break;
  79. case '2': function_name = strdup ("operator_new"); break;
  80. case '3': function_name = strdup ("operator_delete"); break;
  81. case '4': function_name = strdup ("operator_equals"); break;
  82. case '5': function_name = strdup ("operator_shiftright"); break;
  83. case '6': function_name = strdup ("operator_shiftleft"); break;
  84. case '7': function_name = strdup ("operator_not"); break;
  85. case '8': function_name = strdup ("operator_equalsequals"); break;
  86. case '9': function_name = strdup ("operator_notequals"); break;
  87. case 'A': function_name = strdup ("operator_array"); break;
  88. case 'C': function_name = strdup ("operator_dereference"); break;
  89. case 'D': function_name = strdup ("operator_multiply"); break;
  90. case 'E': function_name = strdup ("operator_plusplus"); break;
  91. case 'F': function_name = strdup ("operator_minusminus"); break;
  92. case 'G': function_name = strdup ("operator_minus"); break;
  93. case 'H': function_name = strdup ("operator_plus"); break;
  94. case 'I': function_name = strdup ("operator_address"); break;
  95. case 'J': function_name = strdup ("operator_dereferencememberptr"); break;
  96. case 'K': function_name = strdup ("operator_divide"); break;
  97. case 'L': function_name = strdup ("operator_modulo"); break;
  98. case 'M': function_name = strdup ("operator_lessthan"); break;
  99. case 'N': function_name = strdup ("operator_lessthanequal"); break;
  100. case 'O': function_name = strdup ("operator_greaterthan"); break;
  101. case 'P': function_name = strdup ("operator_greaterthanequal"); break;
  102. case 'Q': function_name = strdup ("operator_comma"); break;
  103. case 'R': function_name = strdup ("operator_functioncall"); break;
  104. case 'S': function_name = strdup ("operator_complement"); break;
  105. case 'T': function_name = strdup ("operator_xor"); break;
  106. case 'U': function_name = strdup ("operator_logicalor"); break;
  107. case 'V': function_name = strdup ("operator_logicaland"); break;
  108. case 'W': function_name = strdup ("operator_or"); break;
  109. case 'X': function_name = strdup ("operator_multiplyequals"); break;
  110. case 'Y': function_name = strdup ("operator_plusequals"); break;
  111. case 'Z': function_name = strdup ("operator_minusequals"); break;
  112. case '_':
  113. switch (*++name)
  114. {
  115. case '0': function_name = strdup ("operator_divideequals"); break;
  116. case '1': function_name = strdup ("operator_moduloequals"); break;
  117. case '2': function_name = strdup ("operator_shiftrightequals"); break;
  118. case '3': function_name = strdup ("operator_shiftleftequals"); break;
  119. case '4': function_name = strdup ("operator_andequals"); break;
  120. case '5': function_name = strdup ("operator_orequals"); break;
  121. case '6': function_name = strdup ("operator_xorequals"); break;
  122. case '7': function_name = strdup ("vftable"); data_flags = DATA_VTABLE; break;
  123. case '8': function_name = strdup ("vbtable"); data_flags = DATA_VTABLE; break;
  124. case '9': function_name = strdup ("vcall"); data_flags = DATA_VTABLE; break;
  125. case 'A': function_name = strdup ("typeof"); data_flags = DATA_VTABLE; break;
  126. case 'B': function_name = strdup ("local_static_guard"); data_flags = DATA_VTABLE; break;
  127. case 'C': function_name = strdup ("string"); data_flags = DATA_VTABLE; break;
  128. case 'D': function_name = strdup ("vbase_dtor"); data_flags = DATA_VTABLE; break;
  129. case 'E': function_name = strdup ("vector_dtor"); break;
  130. case 'G': function_name = strdup ("scalar_dtor"); break;
  131. case 'H': function_name = strdup ("vector_ctor_iter"); break;
  132. case 'I': function_name = strdup ("vector_dtor_iter"); break;
  133. case 'J': function_name = strdup ("vector_vbase_ctor_iter"); break;
  134. case 'L': function_name = strdup ("eh_vector_ctor_iter"); break;
  135. case 'M': function_name = strdup ("eh_vector_dtor_iter"); break;
  136. case 'N': function_name = strdup ("eh_vector_vbase_ctor_iter"); break;
  137. case 'O': function_name = strdup ("copy_ctor_closure"); break;
  138. case 'S': function_name = strdup ("local_vftable"); data_flags = DATA_VTABLE; break;
  139. case 'T': function_name = strdup ("local_vftable_ctor_closure"); break;
  140. case 'U': function_name = strdup ("operator_new_vector"); break;
  141. case 'V': function_name = strdup ("operator_delete_vector"); break;
  142. case 'X': function_name = strdup ("placement_new_closure"); break;
  143. case 'Y': function_name = strdup ("placement_delete_closure"); break;
  144. default:
  145. return FALSE;
  146. }
  147. break;
  148. default:
  149. /* FIXME: Other operators */
  150. return FALSE;
  151. }
  152. name++;
  153. }
  154. else
  155. {
  156. /* Type or function name terminated by '@' */
  157. function_name = name;
  158. while (*name && *name++ != '@') ;
  159. if (!*name)
  160. return FALSE;
  161. function_name = str_substring (function_name, name - 1);
  162. }
  163. /* Either a class name, or '@' if the symbol is not a class member */
  164. if (*name == '@')
  165. {
  166. class_name = strdup ("global"); /* Non member function (or a datatype) */
  167. name++;
  168. }
  169. else
  170. {
  171. /* Class the function is associated with, terminated by '@@' */
  172. class_name = name;
  173. while (*name && *name++ != '@') ;
  174. if (*name++ != '@') {
  175. free (function_name);
  176. return FALSE;
  177. }
  178. class_name = str_substring (class_name, name - 2); /* Allocates a new string */
  179. }
  180. /* Function/Data type and access level */
  181. /* FIXME: why 2 possible letters for each option? */
  182. switch(*name++)
  183. {
  184. /* Data */
  185. case '0' : /* private static */
  186. case '1' : /* protected static */
  187. case '2' : /* public static */
  188. is_static = TRUE;
  189. /* Fall through */
  190. case '3' : /* non static */
  191. case '4' : /* non static */
  192. /* Data members need to be implemented: report */
  193. INIT_CT (ct);
  194. if (!demangle_datatype (&name, &ct, sym))
  195. {
  196. if (VERBOSE)
  197. printf ("/*FIXME: %s: unknown data*/\n", sym->symbol);
  198. free (function_name);
  199. free (class_name);
  200. return FALSE;
  201. }
  202. sym->flags |= SYM_DATA;
  203. sym->argc = 1;
  204. sym->arg_name[0] = str_create (5, OUTPUT_UC_DLL_NAME, "_", class_name,
  205. is_static ? "static_" : "_", function_name);
  206. sym->arg_text[0] = str_create (3, ct.expression, " ", sym->arg_name[0]);
  207. FREE_CT (ct);
  208. free (function_name);
  209. free (class_name);
  210. return TRUE;
  211. case '6' : /* compiler generated static */
  212. case '7' : /* compiler generated static */
  213. if (data_flags & DATA_VTABLE)
  214. {
  215. sym->flags |= SYM_DATA;
  216. sym->argc = 1;
  217. sym->arg_name[0] = str_create (5, OUTPUT_UC_DLL_NAME, "_", class_name,
  218. "_", function_name);
  219. sym->arg_text[0] = str_create (2, "void *", sym->arg_name[0]);
  220. if (VERBOSE)
  221. puts ("Demangled symbol OK [vtable]");
  222. free (function_name);
  223. free (class_name);
  224. return TRUE;
  225. }
  226. free (function_name);
  227. free (class_name);
  228. return FALSE;
  229. /* Functions */
  230. case 'E' : /* private virtual */
  231. case 'F' : /* private virtual */
  232. case 'M' : /* protected virtual */
  233. case 'N' : /* protected virtual */
  234. case 'U' : /* public virtual */
  235. case 'V' : /* public virtual */
  236. /* Virtual functions need to be added to the exported vtable: report */
  237. if (VERBOSE)
  238. printf ("/*FIXME %s: %s::%s is virtual-add to vftable*/\n", sym->symbol,
  239. class_name, function_name);
  240. /* Fall through */
  241. case 'A' : /* private */
  242. case 'B' : /* private */
  243. case 'I' : /* protected */
  244. case 'J' : /* protected */
  245. case 'Q' : /* public */
  246. case 'R' : /* public */
  247. /* Implicit 'this' pointer */
  248. sym->arg_text [sym->argc] = str_create (3, "struct ", class_name, " *");
  249. sym->arg_type [sym->argc] = ARG_POINTER;
  250. sym->arg_flag [sym->argc] = 0;
  251. sym->arg_name [sym->argc++] = strdup ("_this");
  252. /* New struct definitions can be 'grep'ed out for making a fixup header */
  253. if (VERBOSE)
  254. printf ("struct %s { void **vtable; /*FIXME: class definition */ };\n", class_name);
  255. break;
  256. case 'C' : /* private: static */
  257. case 'D' : /* private: static */
  258. case 'K' : /* protected: static */
  259. case 'L' : /* protected: static */
  260. case 'S' : /* public: static */
  261. case 'T' : /* public: static */
  262. is_static = TRUE; /* No implicit this pointer */
  263. break;
  264. case 'Y' :
  265. case 'Z' :
  266. break;
  267. /* FIXME: G,H / O,P / W,X are private / protected / public thunks */
  268. default:
  269. free (function_name);
  270. free (class_name);
  271. return FALSE;
  272. }
  273. /* If there is an implicit this pointer, const status follows */
  274. if (sym->argc)
  275. {
  276. switch (*name++)
  277. {
  278. case 'A': break; /* non-const */
  279. case 'B': is_const = CT_CONST; break;
  280. case 'C': is_const = CT_VOLATILE; break;
  281. case 'D': is_const = (CT_CONST | CT_VOLATILE); break;
  282. default:
  283. free (function_name);
  284. free (class_name);
  285. return FALSE;
  286. }
  287. }
  288. /* Next is the calling convention */
  289. switch (*name++)
  290. {
  291. case 'A': /* __cdecl */
  292. case 'B': /* __cdecl __declspec(dllexport) */
  293. if (!sym->argc)
  294. {
  295. sym->flags |= SYM_CDECL;
  296. break;
  297. }
  298. /* Else fall through */
  299. case 'C': /* __pascal */
  300. case 'D': /* __pascal __declspec(dllexport) */
  301. case 'E': /* __thiscall */
  302. case 'F': /* __thiscall __declspec(dllexport) */
  303. case 'G': /* __stdcall */
  304. case 'H': /* __stdcall __declspec(dllexport) */
  305. case 'I': /* __fastcall */
  306. case 'J': /* __fastcall __declspec(dllexport)*/
  307. case 'K': /* default (none given) */
  308. if (sym->argc)
  309. sym->flags |= SYM_THISCALL;
  310. else
  311. sym->flags |= SYM_STDCALL;
  312. break;
  313. default:
  314. free (function_name);
  315. free (class_name);
  316. return FALSE;
  317. }
  318. /* Return type, or @ if 'void' */
  319. if (*name == '@')
  320. {
  321. sym->return_text = strdup ("void");
  322. sym->return_type = ARG_VOID;
  323. name++;
  324. }
  325. else
  326. {
  327. INIT_CT (ct);
  328. if (!demangle_datatype (&name, &ct, sym)) {
  329. free (function_name);
  330. free (class_name);
  331. return FALSE;
  332. }
  333. sym->return_text = ct.expression;
  334. sym->return_type = get_type_constant(ct.dest_type, ct.flags);
  335. ct.expression = NULL;
  336. FREE_CT (ct);
  337. }
  338. /* Now come the function arguments */
  339. while (*name && *name != 'Z')
  340. {
  341. /* Decode each data type and append it to the argument list */
  342. if (*name != '@')
  343. {
  344. INIT_CT (ct);
  345. if (!demangle_datatype(&name, &ct, sym)) {
  346. free (function_name);
  347. free (class_name);
  348. return FALSE;
  349. }
  350. if (strcmp (ct.expression, "void"))
  351. {
  352. sym->arg_text [sym->argc] = ct.expression;
  353. ct.expression = NULL;
  354. sym->arg_type [sym->argc] = get_type_constant (ct.dest_type, ct.flags);
  355. sym->arg_flag [sym->argc] = ct.flags;
  356. sym->arg_name[sym->argc] = str_create_num (1, sym->argc, "arg");
  357. sym->argc++;
  358. }
  359. else
  360. break; /* 'void' terminates an argument list */
  361. FREE_CT (ct);
  362. }
  363. else
  364. name++;
  365. }
  366. while (*name == '@')
  367. name++;
  368. /* Functions are always terminated by 'Z'. If we made it this far and
  369. * Don't find it, we have incorrectly identified a data type.
  370. */
  371. if (*name != 'Z') {
  372. free (function_name);
  373. free (class_name);
  374. return FALSE;
  375. }
  376. /* Note: '()' after 'Z' means 'throws', but we don't care here */
  377. /* Create the function name. Include a unique number because otherwise
  378. * overloaded functions could have the same c signature.
  379. */
  380. switch (is_const)
  381. {
  382. case (CT_CONST | CT_VOLATILE): const_status = "_const_volatile"; break;
  383. case CT_CONST: const_status = "_const"; break;
  384. case CT_VOLATILE: const_status = "_volatile"; break;
  385. default: const_status = "_"; break;
  386. }
  387. sym->function_name = str_create_num (4, hash, class_name, "_",
  388. function_name, is_static ? "_static" : const_status);
  389. assert (sym->return_text);
  390. assert (sym->flags);
  391. assert (sym->function_name);
  392. free (class_name);
  393. free (function_name);
  394. if (VERBOSE)
  395. puts ("Demangled symbol OK");
  396. return TRUE;
  397. }
  398. /*******************************************************************
  399. * demangle_datatype
  400. *
  401. * Attempt to demangle a C++ data type, which may be compound.
  402. * a compound type is made up of a number of simple types. e.g:
  403. * char** = (pointer to (pointer to (char)))
  404. *
  405. * Uses a simple recursive descent algorithm that is broken
  406. * and/or incomplete, without a doubt ;-)
  407. */
  408. static char *demangle_datatype (char **str, compound_type *ct,
  409. parsed_symbol* sym)
  410. {
  411. char *iter;
  412. assert (str && *str);
  413. assert (ct);
  414. iter = *str;
  415. if (!get_constraints_convention_1 (&iter, ct))
  416. return NULL;
  417. if (*iter == '_')
  418. {
  419. /* MS type: __int8,__int16 etc */
  420. ct->flags |= CT_EXTENDED;
  421. iter++;
  422. }
  423. switch (*iter)
  424. {
  425. case 'C': case 'D': case 'E': case 'F': case 'G':
  426. case 'H': case 'I': case 'J': case 'K': case 'M':
  427. case 'N': case 'O': case 'X': case 'Z':
  428. /* Simple data types */
  429. ct->dest_type = *iter++;
  430. if (!get_constraints_convention_2 (&iter, ct))
  431. return NULL;
  432. ct->expression = get_type_string (ct->dest_type, ct->flags);
  433. break;
  434. case 'U':
  435. case 'V':
  436. /* Class/struct/union */
  437. ct->dest_type = *iter++;
  438. if (*iter == '0' || *iter == '1')
  439. {
  440. /* Referring to class type (implicit 'this') */
  441. char *stripped;
  442. if (!sym->argc)
  443. return NULL;
  444. iter++;
  445. /* Apply our constraints to the base type (struct xxx *) */
  446. stripped = strdup (sym->arg_text [0]);
  447. if (!stripped)
  448. fatal ("Out of Memory");
  449. /* If we're a reference, re-use the pointer already in the type */
  450. if (!(ct->flags & CT_BY_REFERENCE))
  451. stripped[ strlen (stripped) - 2] = '\0'; /* otherwise, strip it */
  452. ct->expression = str_create (2, ct->flags & CT_CONST ? "const " :
  453. ct->flags & CT_VOLATILE ? "volatile " : "", stripped);
  454. free (stripped);
  455. }
  456. else if (*iter != '@')
  457. {
  458. /* The name of the class/struct, followed by '@@' */
  459. char *struct_name = iter;
  460. while (*iter && *iter++ != '@') ;
  461. if (*iter++ != '@')
  462. return NULL;
  463. struct_name = str_substring (struct_name, iter - 2);
  464. ct->expression = str_create (4, ct->flags & CT_CONST ? "const " :
  465. ct->flags & CT_VOLATILE ? "volatile " : "", "struct ",
  466. struct_name, ct->flags & CT_BY_REFERENCE ? " *" : "");
  467. free (struct_name);
  468. }
  469. break;
  470. case 'Q': /* FIXME: Array Just treated as pointer currently */
  471. case 'P': /* Pointer */
  472. {
  473. compound_type sub_ct;
  474. INIT_CT (sub_ct);
  475. ct->dest_type = *iter++;
  476. if (!get_constraints_convention_2 (&iter, ct))
  477. return NULL;
  478. /* FIXME: P6 = Function pointer, others who knows.. */
  479. if (isdigit (*iter))
  480. {
  481. if (*iter == '6')
  482. {
  483. int sub_expressions = 0;
  484. /* FIXME: there are tons of memory leaks here */
  485. /* FIXME: this is still broken in some cases and it has to be
  486. * merged with the function prototype parsing above...
  487. */
  488. iter += iter[1] == 'A' ? 2 : 3; /* FIXME */
  489. if (!demangle_datatype (&iter, &sub_ct, sym))
  490. return NULL;
  491. ct->expression = str_create(2, sub_ct.expression, " (*)(");
  492. if (*iter != '@')
  493. {
  494. while (*iter != 'Z')
  495. {
  496. FREE_CT (sub_ct);
  497. INIT_CT (sub_ct);
  498. if (!demangle_datatype (&iter, &sub_ct, sym))
  499. return NULL;
  500. if (sub_expressions)
  501. ct->expression = str_create(3, ct->expression, ", ", sub_ct.expression);
  502. else
  503. ct->expression = str_create(2, ct->expression, sub_ct.expression);
  504. while (*iter == '@') iter++;
  505. sub_expressions++;
  506. }
  507. } else while (*iter == '@') iter++;
  508. iter++;
  509. ct->expression = str_create(2, ct->expression, ")");
  510. }
  511. else
  512. return NULL;
  513. }
  514. else
  515. {
  516. /* Recurse to get the pointed-to type */
  517. if (!demangle_datatype (&iter, &sub_ct, sym))
  518. return NULL;
  519. ct->expression = get_pointer_type_string (ct, sub_ct.expression);
  520. }
  521. FREE_CT (sub_ct);
  522. }
  523. break;
  524. case '0': case '1': case '2': case '3': case '4':
  525. case '5': case '6': case '7': case '8': case '9':
  526. /* Referring back to previously parsed type */
  527. if (sym->argc >= (size_t)('0' - *iter))
  528. return NULL;
  529. ct->dest_type = sym->arg_type ['0' - *iter];
  530. ct->expression = strdup (sym->arg_text ['0' - *iter]);
  531. iter++;
  532. break;
  533. default :
  534. return NULL;
  535. }
  536. if (!ct->expression)
  537. return NULL;
  538. return *str = iter;
  539. }
  540. /* Constraints:
  541. * There are two conventions for specifying data type constants. I
  542. * don't know how the compiler chooses between them, but I suspect it
  543. * is based on ensuring that linker names are unique.
  544. * Convention 1. The data type modifier is given first, followed
  545. * by the data type it operates on. '?' means passed by value,
  546. * 'A' means passed by reference. Note neither of these characters
  547. * is a valid base data type. This is then followed by a character
  548. * specifying constness or volatility.
  549. * Convention 2. The base data type (which is never '?' or 'A') is
  550. * given first. The character modifier is optionally given after
  551. * the base type character. If a valid character modifier is present,
  552. * then it only applies to the current data type if the character
  553. * after that is not 'A' 'B' or 'C' (Because this makes a convention 1
  554. * constraint for the next data type).
  555. *
  556. * The conventions are usually mixed within the same symbol.
  557. * Since 'C' is both a qualifier and a data type, I suspect that
  558. * convention 1 allows specifying e.g. 'volatile signed char*'. In
  559. * convention 2 this would be 'CC' which is ambiguous (i.e. Is it two
  560. * pointers, or a single pointer + modifier?). In convention 1 it
  561. * is encoded as '?CC' which is not ambiguous. This probably
  562. * holds true for some other types as well.
  563. */
  564. /*******************************************************************
  565. * get_constraints_convention_1
  566. *
  567. * Get type constraint information for a data type
  568. */
  569. static char *get_constraints_convention_1 (char **str, compound_type *ct)
  570. {
  571. char *iter = *str, **retval = str;
  572. if (ct->have_qualifiers)
  573. return *str; /* Previously got constraints for this type */
  574. if (*iter == '?' || *iter == 'A')
  575. {
  576. ct->have_qualifiers = TRUE;
  577. ct->flags |= (*iter++ == '?' ? 0 : CT_BY_REFERENCE);
  578. switch (*iter++)
  579. {
  580. case 'A' :
  581. break; /* non-const, non-volatile */
  582. case 'B' :
  583. ct->flags |= CT_CONST;
  584. break;
  585. case 'C' :
  586. ct->flags |= CT_VOLATILE;
  587. break;
  588. default :
  589. return NULL;
  590. }
  591. }
  592. return *retval = iter;
  593. }
  594. /*******************************************************************
  595. * get_constraints_convention_2
  596. *
  597. * Get type constraint information for a data type
  598. */
  599. static char *get_constraints_convention_2 (char **str, compound_type *ct)
  600. {
  601. char *iter = *str, **retval = str;
  602. /* FIXME: Why do arrays have both convention 1 & 2 constraints? */
  603. if (ct->have_qualifiers && ct->dest_type != 'Q')
  604. return *str; /* Previously got constraints for this type */
  605. ct->have_qualifiers = TRUE; /* Even if none, we've got all we're getting */
  606. switch (*iter)
  607. {
  608. case 'A' :
  609. if (iter[1] != 'A' && iter[1] != 'B' && iter[1] != 'C')
  610. iter++;
  611. break;
  612. case 'B' :
  613. ct->flags |= CT_CONST;
  614. iter++;
  615. break;
  616. case 'C' :
  617. /* See note above, if we find 'C' it is _not_ a signed char */
  618. ct->flags |= CT_VOLATILE;
  619. iter++;
  620. break;
  621. }
  622. return *retval = iter;
  623. }
  624. /*******************************************************************
  625. * get_type_string
  626. *
  627. * Return a string containing the name of a data type
  628. */
  629. static char *get_type_string (const char c, const int constraints)
  630. {
  631. const char *type_string;
  632. if (constraints & CT_EXTENDED)
  633. {
  634. switch (c)
  635. {
  636. case 'D': type_string = "__int8"; break;
  637. case 'E': type_string = "unsigned __int8"; break;
  638. case 'F': type_string = "__int16"; break;
  639. case 'G': type_string = "unsigned __int16"; break;
  640. case 'H': type_string = "__int32"; break;
  641. case 'I': type_string = "unsigned __int32"; break;
  642. case 'J': type_string = "__int64"; break;
  643. case 'K': type_string = "unsigned __int64"; break;
  644. case 'L': type_string = "__int128"; break;
  645. case 'M': type_string = "unsigned __int128"; break;
  646. case 'N': type_string = "int"; break; /* bool */
  647. case 'W': type_string = "WCHAR"; break; /* wchar_t */
  648. default:
  649. return NULL;
  650. }
  651. }
  652. else
  653. {
  654. switch (c)
  655. {
  656. case 'C': /* Signed char, fall through */
  657. case 'D': type_string = "char"; break;
  658. case 'E': type_string = "unsigned char"; break;
  659. case 'F': type_string = "short int"; break;
  660. case 'G': type_string = "unsigned short int"; break;
  661. case 'H': type_string = "int"; break;
  662. case 'I': type_string = "unsigned int"; break;
  663. case 'J': type_string = "long"; break;
  664. case 'K': type_string = "unsigned long"; break;
  665. case 'M': type_string = "float"; break;
  666. case 'N': type_string = "double"; break;
  667. case 'O': type_string = "long double"; break;
  668. /* FIXME: T = union */
  669. case 'U':
  670. case 'V': type_string = "struct"; break;
  671. case 'X': return strdup ("void");
  672. case 'Z': return strdup ("...");
  673. default:
  674. return NULL;
  675. }
  676. }
  677. return str_create (3, constraints & CT_CONST ? "const " :
  678. constraints & CT_VOLATILE ? "volatile " : "", type_string,
  679. constraints & CT_BY_REFERENCE ? " *" : "");
  680. }
  681. /*******************************************************************
  682. * get_type_constant
  683. *
  684. * Get the ARG_* constant for this data type
  685. */
  686. static int get_type_constant (const char c, const int constraints)
  687. {
  688. /* Any reference type is really a pointer */
  689. if (constraints & CT_BY_REFERENCE)
  690. return ARG_POINTER;
  691. switch (c)
  692. {
  693. case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
  694. case 'J': case 'K':
  695. return ARG_LONG;
  696. case 'M':
  697. return ARG_FLOAT;
  698. case 'N': case 'O':
  699. return ARG_DOUBLE;
  700. case 'P': case 'Q':
  701. return ARG_POINTER;
  702. case 'U': case 'V':
  703. return ARG_STRUCT;
  704. case 'X':
  705. return ARG_VOID;
  706. case 'Z':
  707. default:
  708. return -1;
  709. }
  710. }
  711. /*******************************************************************
  712. * get_pointer_type_string
  713. *
  714. * Return a string containing 'pointer to expression'
  715. */
  716. static char *get_pointer_type_string (compound_type *ct,
  717. const char *expression)
  718. {
  719. /* FIXME: set a compound flag for bracketing expression if needed */
  720. return str_create (3, ct->flags & CT_CONST ? "const " :
  721. ct->flags & CT_VOLATILE ? "volatile " : "", expression,
  722. ct->flags & CT_BY_REFERENCE ? " **" : " *");
  723. }