/tags/rel-2.0.0/trunk/Source/Swig/typesys.c

# · C · 2073 lines · 1444 code · 206 blank · 423 comment · 343 complexity · fef339c00239f2d36ab0acbf39922f36 MD5 · raw file

Large files are truncated click here to view the full file

  1. /* -----------------------------------------------------------------------------
  2. * This file is part of SWIG, which is licensed as a whole under version 3
  3. * (or any later version) of the GNU General Public License. Some additional
  4. * terms also apply to certain portions of SWIG. The full details of the SWIG
  5. * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6. * included with the SWIG source code as distributed by the SWIG developers
  7. * and at http://www.swig.org/legal.html.
  8. *
  9. * typesys.c
  10. *
  11. * SWIG type system management. These functions are used to manage
  12. * the C++ type system including typenames, typedef, type scopes,
  13. * inheritance, and namespaces. Generation of support code for the
  14. * run-time type checker is also handled here.
  15. * ----------------------------------------------------------------------------- */
  16. char cvsroot_typesys_c[] = "$Id: typesys.c 12025 2010-05-14 04:10:19Z olly $";
  17. #include "swig.h"
  18. #include "cparse.h"
  19. /* -----------------------------------------------------------------------------
  20. * Synopsis
  21. *
  22. * The purpose of this module is to manage type names and scoping issues related
  23. * to the C++ type system. The primary use is tracking typenames through typedef
  24. * and inheritance.
  25. *
  26. * New typenames are introduced by typedef, class, and enum declarations.
  27. * Each type is declared in a scope. This is either the global scope, a
  28. * class, or a namespace. For example:
  29. *
  30. * typedef int A; // Typename A, in global scope
  31. * namespace Foo {
  32. * typedef int A; // Typename A, in scope Foo::
  33. * }
  34. * class Bar { // Typename Bar, in global scope
  35. * typedef int A; // Typename A, in scope Bar::
  36. * }
  37. *
  38. * To manage scopes, the type system is constructed as a tree of hash tables. Each
  39. * hash table contains the following attributes:
  40. *
  41. * "name" - Scope name
  42. * "qname" - Fully qualified typename
  43. * "typetab" - Type table containing typenames and typedef information
  44. * "symtab" - Hash table of symbols defined in a scope
  45. * "inherit" - List of inherited scopes
  46. * "parent" - Parent scope
  47. *
  48. * Typedef information is stored in the "typetab" hash table. For example,
  49. * if you have these declarations:
  50. *
  51. * typedef int A;
  52. * typedef A B;
  53. * typedef B *C;
  54. *
  55. * typetab is built as follows:
  56. *
  57. * "A" : "int"
  58. * "B" : "A"
  59. * "C" : "p.B"
  60. *
  61. * To resolve a type back to its root type, one repeatedly expands on the type base.
  62. * For example:
  63. *
  64. * C *[40] ---> a(40).p.C (string type representation, see stype.c)
  65. * ---> a(40).p.p.B (C --> p.B)
  66. * ---> a(40).p.p.A (B --> A)
  67. * ---> a(40).p.p.int (A --> int)
  68. *
  69. * For inheritance, SWIG tries to resolve types back to the base class. For instance, if
  70. * you have this:
  71. *
  72. * class Foo {
  73. * public:
  74. * typedef int Integer;
  75. * };
  76. *
  77. * class Bar : public Foo {
  78. * void blah(Integer x);
  79. * };
  80. *
  81. * The argument type of Bar::blah will be set to Foo::Integer.
  82. *
  83. * The scope-inheritance mechanism is used to manage C++ namespace aliases.
  84. * For example, if you have this:
  85. *
  86. * namespace Foo {
  87. * typedef int Integer;
  88. * }
  89. *
  90. * namespace F = Foo;
  91. *
  92. * In this case, "F::" is defined as a scope that "inherits" from Foo. Internally,
  93. * "F::" will merely be an empty scope that refers to Foo. SWIG will never
  94. * place new type information into a namespace alias---attempts to do so
  95. * will generate a warning message (in the parser) and will place information into
  96. * Foo instead.
  97. *
  98. *----------------------------------------------------------------------------- */
  99. static Typetab *current_scope = 0; /* Current type scope */
  100. static Hash *current_typetab = 0; /* Current type table */
  101. static Hash *current_symtab = 0; /* Current symbol table */
  102. static Typetab *global_scope = 0; /* The global scope */
  103. static Hash *scopes = 0; /* Hash table containing fully qualified scopes */
  104. /* Performance optimization */
  105. #define SWIG_TYPEDEF_RESOLVE_CACHE
  106. static Hash *typedef_resolve_cache = 0;
  107. static Hash *typedef_all_cache = 0;
  108. static Hash *typedef_qualified_cache = 0;
  109. static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix);
  110. /* common attribute keys, to avoid calling find_key all the times */
  111. /*
  112. Enable this one if your language fully support SwigValueWrapper<T>.
  113. Leaving at '0' keeps the old swig behavior, which is not
  114. always safe, but is well known.
  115. Setting at '1' activates the new scheme, which is always safe but
  116. it requires all the typemaps to be ready for that.
  117. */
  118. static int value_wrapper_mode = 0;
  119. int Swig_value_wrapper_mode(int mode) {
  120. value_wrapper_mode = mode;
  121. return mode;
  122. }
  123. static void flush_cache() {
  124. typedef_resolve_cache = 0;
  125. typedef_all_cache = 0;
  126. typedef_qualified_cache = 0;
  127. }
  128. /* Initialize the scoping system */
  129. void SwigType_typesystem_init() {
  130. if (global_scope)
  131. Delete(global_scope);
  132. if (scopes)
  133. Delete(scopes);
  134. current_scope = NewHash();
  135. global_scope = current_scope;
  136. Setattr(current_scope, "name", ""); /* No name for global scope */
  137. current_typetab = NewHash();
  138. Setattr(current_scope, "typetab", current_typetab);
  139. current_symtab = 0;
  140. scopes = NewHash();
  141. Setattr(scopes, "", current_scope);
  142. }
  143. /* -----------------------------------------------------------------------------
  144. * SwigType_typedef()
  145. *
  146. * Defines a new typedef in the current scope. Returns -1 if the type name is
  147. * already defined.
  148. * ----------------------------------------------------------------------------- */
  149. int SwigType_typedef(SwigType *type, const_String_or_char_ptr name) {
  150. if (Getattr(current_typetab, name))
  151. return -1; /* Already defined */
  152. if (Strcmp(type, name) == 0) { /* Can't typedef a name to itself */
  153. return 0;
  154. }
  155. /* Check if 'type' is already a scope. If so, we create an alias in the type
  156. system for it. This is needed to make strange nested scoping problems work
  157. correctly. */
  158. {
  159. Typetab *t = SwigType_find_scope(current_scope, type);
  160. if (t) {
  161. SwigType_new_scope(name);
  162. SwigType_inherit_scope(t);
  163. SwigType_pop_scope();
  164. }
  165. }
  166. Setattr(current_typetab, name, type);
  167. flush_cache();
  168. return 0;
  169. }
  170. /* -----------------------------------------------------------------------------
  171. * SwigType_typedef_class()
  172. *
  173. * Defines a class in the current scope.
  174. * ----------------------------------------------------------------------------- */
  175. int SwigType_typedef_class(const_String_or_char_ptr name) {
  176. String *cname;
  177. /* Printf(stdout,"class : '%s'\n", name); */
  178. if (Getattr(current_typetab, name))
  179. return -1; /* Already defined */
  180. cname = NewString(name);
  181. Setmeta(cname, "class", "1");
  182. Setattr(current_typetab, cname, cname);
  183. Delete(cname);
  184. flush_cache();
  185. return 0;
  186. }
  187. /* -----------------------------------------------------------------------------
  188. * SwigType_scope_name()
  189. *
  190. * Returns the qualified scope name of a type table
  191. * ----------------------------------------------------------------------------- */
  192. String *SwigType_scope_name(Typetab *ttab) {
  193. String *qname = NewString(Getattr(ttab, "name"));
  194. ttab = Getattr(ttab, "parent");
  195. while (ttab) {
  196. String *pname = Getattr(ttab, "name");
  197. if (Len(pname)) {
  198. Insert(qname, 0, "::");
  199. Insert(qname, 0, pname);
  200. }
  201. ttab = Getattr(ttab, "parent");
  202. }
  203. return qname;
  204. }
  205. /* -----------------------------------------------------------------------------
  206. * SwigType_new_scope()
  207. *
  208. * Creates a new scope
  209. * ----------------------------------------------------------------------------- */
  210. void SwigType_new_scope(const_String_or_char_ptr name) {
  211. Typetab *s;
  212. Hash *ttab;
  213. String *qname;
  214. if (!name) {
  215. name = "<unnamed>";
  216. }
  217. s = NewHash();
  218. Setattr(s, "name", name);
  219. Setattr(s, "parent", current_scope);
  220. ttab = NewHash();
  221. Setattr(s, "typetab", ttab);
  222. /* Build fully qualified name and */
  223. qname = SwigType_scope_name(s);
  224. Setattr(scopes, qname, s);
  225. Setattr(s, "qname", qname);
  226. Delete(qname);
  227. current_scope = s;
  228. current_typetab = ttab;
  229. current_symtab = 0;
  230. flush_cache();
  231. }
  232. /* -----------------------------------------------------------------------------
  233. * SwigType_inherit_scope()
  234. *
  235. * Makes the current scope inherit from another scope. This is used for both
  236. * C++ class inheritance, namespaces, and namespace aliases.
  237. * ----------------------------------------------------------------------------- */
  238. void SwigType_inherit_scope(Typetab *scope) {
  239. List *inherits;
  240. int i, len;
  241. inherits = Getattr(current_scope, "inherit");
  242. if (!inherits) {
  243. inherits = NewList();
  244. Setattr(current_scope, "inherit", inherits);
  245. Delete(inherits);
  246. }
  247. assert(scope != current_scope);
  248. len = Len(inherits);
  249. for (i = 0; i < len; i++) {
  250. Node *n = Getitem(inherits, i);
  251. if (n == scope)
  252. return;
  253. }
  254. Append(inherits, scope);
  255. }
  256. /* -----------------------------------------------------------------------------
  257. * SwigType_scope_alias()
  258. *
  259. * Creates a scope-alias.
  260. * ----------------------------------------------------------------------------- */
  261. void SwigType_scope_alias(String *aliasname, Typetab *ttab) {
  262. String *q;
  263. /* Printf(stdout,"alias: '%s' '%x'\n", aliasname, ttab); */
  264. q = SwigType_scope_name(current_scope);
  265. if (Len(q)) {
  266. Append(q, "::");
  267. }
  268. Append(q, aliasname);
  269. Setattr(scopes, q, ttab);
  270. flush_cache();
  271. }
  272. /* -----------------------------------------------------------------------------
  273. * SwigType_using_scope()
  274. *
  275. * Import another scope into this scope.
  276. * ----------------------------------------------------------------------------- */
  277. void SwigType_using_scope(Typetab *scope) {
  278. SwigType_inherit_scope(scope);
  279. {
  280. List *ulist;
  281. int i, len;
  282. ulist = Getattr(current_scope, "using");
  283. if (!ulist) {
  284. ulist = NewList();
  285. Setattr(current_scope, "using", ulist);
  286. Delete(ulist);
  287. }
  288. assert(scope != current_scope);
  289. len = Len(ulist);
  290. for (i = 0; i < len; i++) {
  291. Typetab *n = Getitem(ulist, i);
  292. if (n == scope)
  293. return;
  294. }
  295. Append(ulist, scope);
  296. }
  297. flush_cache();
  298. }
  299. /* -----------------------------------------------------------------------------
  300. * SwigType_pop_scope()
  301. *
  302. * Pop off the last scope and perform a merge operation. Returns the hash
  303. * table for the scope that was popped off.
  304. * ----------------------------------------------------------------------------- */
  305. Typetab *SwigType_pop_scope() {
  306. Typetab *t, *old = current_scope;
  307. t = Getattr(current_scope, "parent");
  308. if (!t)
  309. t = global_scope;
  310. current_scope = t;
  311. current_typetab = Getattr(t, "typetab");
  312. current_symtab = Getattr(t, "symtab");
  313. flush_cache();
  314. return old;
  315. }
  316. /* -----------------------------------------------------------------------------
  317. * SwigType_set_scope()
  318. *
  319. * Set the scope. Returns the old scope.
  320. * ----------------------------------------------------------------------------- */
  321. Typetab *SwigType_set_scope(Typetab *t) {
  322. Typetab *old = current_scope;
  323. if (!t)
  324. t = global_scope;
  325. current_scope = t;
  326. current_typetab = Getattr(t, "typetab");
  327. current_symtab = Getattr(t, "symtab");
  328. flush_cache();
  329. return old;
  330. }
  331. /* -----------------------------------------------------------------------------
  332. * SwigType_attach_symtab()
  333. *
  334. * Attaches a symbol table to a type scope
  335. * ----------------------------------------------------------------------------- */
  336. void SwigType_attach_symtab(Symtab *sym) {
  337. Setattr(current_scope, "symtab", sym);
  338. current_symtab = sym;
  339. }
  340. /* -----------------------------------------------------------------------------
  341. * SwigType_print_scope()
  342. *
  343. * Debugging function for printing out current scope
  344. * ----------------------------------------------------------------------------- */
  345. void SwigType_print_scope(Typetab *t) {
  346. Hash *ttab;
  347. Iterator i, j;
  348. for (i = First(scopes); i.key; i = Next(i)) {
  349. t = i.item;
  350. ttab = Getattr(i.item, "typetab");
  351. Printf(stdout, "Type scope '%s' (%x)\n", i.key, i.item);
  352. {
  353. List *inherit = Getattr(i.item, "inherit");
  354. if (inherit) {
  355. Iterator j;
  356. for (j = First(inherit); j.item; j = Next(j)) {
  357. Printf(stdout, " Inherits from '%s' (%x)\n", Getattr(j.item, "qname"), j.item);
  358. }
  359. }
  360. }
  361. Printf(stdout, "-------------------------------------------------------------\n");
  362. for (j = First(ttab); j.key; j = Next(j)) {
  363. Printf(stdout, "%40s -> %s\n", j.key, j.item);
  364. }
  365. }
  366. }
  367. static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) {
  368. Typetab *ss;
  369. String *nnameprefix = 0;
  370. static int check_parent = 1;
  371. /* Printf(stdout,"find_scope: %x(%s) '%s'\n", s, Getattr(s,"name"), nameprefix); */
  372. if (SwigType_istemplate(nameprefix)) {
  373. nnameprefix = SwigType_typedef_resolve_all(nameprefix);
  374. nameprefix = nnameprefix;
  375. }
  376. ss = s;
  377. while (ss) {
  378. String *full;
  379. String *qname = Getattr(ss, "qname");
  380. if (qname) {
  381. full = NewStringf("%s::%s", qname, nameprefix);
  382. } else {
  383. full = NewString(nameprefix);
  384. }
  385. if (Getattr(scopes, full)) {
  386. s = Getattr(scopes, full);
  387. } else {
  388. s = 0;
  389. }
  390. Delete(full);
  391. if (s) {
  392. if (nnameprefix)
  393. Delete(nnameprefix);
  394. return s;
  395. }
  396. if (!s) {
  397. /* Check inheritance */
  398. List *inherit;
  399. inherit = Getattr(ss, "using");
  400. if (inherit) {
  401. Typetab *ttab;
  402. int i, len;
  403. len = Len(inherit);
  404. for (i = 0; i < len; i++) {
  405. int oldcp = check_parent;
  406. ttab = Getitem(inherit, i);
  407. check_parent = 0;
  408. s = SwigType_find_scope(ttab, nameprefix);
  409. check_parent = oldcp;
  410. if (s) {
  411. if (nnameprefix)
  412. Delete(nnameprefix);
  413. return s;
  414. }
  415. }
  416. }
  417. }
  418. if (!check_parent)
  419. break;
  420. ss = Getattr(ss, "parent");
  421. }
  422. if (nnameprefix)
  423. Delete(nnameprefix);
  424. return 0;
  425. }
  426. /* -----------------------------------------------------------------------------
  427. * typedef_resolve()
  428. *
  429. * Resolves a typedef and returns a new type string. Returns 0 if there is no
  430. * typedef mapping. base is a name without qualification.
  431. * Internal function.
  432. * ----------------------------------------------------------------------------- */
  433. static Typetab *resolved_scope = 0;
  434. /* Internal function */
  435. static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) {
  436. Hash *ttab;
  437. SwigType *type = 0;
  438. List *inherit;
  439. Typetab *parent;
  440. /* if (!s) return 0; *//* now is checked bellow */
  441. /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */
  442. if (!Getmark(s)) {
  443. Setmark(s, 1);
  444. ttab = Getattr(s, "typetab");
  445. type = Getattr(ttab, base);
  446. if (type) {
  447. resolved_scope = s;
  448. Setmark(s, 0);
  449. } else {
  450. /* Hmmm. Not found in my scope. It could be in an inherited scope */
  451. inherit = Getattr(s, "inherit");
  452. if (inherit) {
  453. int i, len;
  454. len = Len(inherit);
  455. for (i = 0; i < len; i++) {
  456. type = _typedef_resolve(Getitem(inherit, i), base, 0);
  457. if (type) {
  458. Setmark(s, 0);
  459. break;
  460. }
  461. }
  462. }
  463. if (!type) {
  464. /* Hmmm. Not found in my scope. check parent */
  465. if (look_parent) {
  466. parent = Getattr(s, "parent");
  467. type = parent ? _typedef_resolve(parent, base, 1) : 0;
  468. }
  469. }
  470. Setmark(s, 0);
  471. }
  472. }
  473. return type;
  474. }
  475. static SwigType *typedef_resolve(Typetab *s, String *base) {
  476. return _typedef_resolve(s, base, 1);
  477. }
  478. /* -----------------------------------------------------------------------------
  479. * SwigType_typedef_resolve()
  480. * ----------------------------------------------------------------------------- */
  481. /* #define SWIG_DEBUG */
  482. SwigType *SwigType_typedef_resolve(const SwigType *t) {
  483. String *base;
  484. String *type = 0;
  485. String *r = 0;
  486. Typetab *s;
  487. Hash *ttab;
  488. String *namebase = 0;
  489. String *nameprefix = 0;
  490. int newtype = 0;
  491. /*
  492. if (!noscope) {
  493. noscope = NewStringEmpty();
  494. }
  495. */
  496. resolved_scope = 0;
  497. #ifdef SWIG_TYPEDEF_RESOLVE_CACHE
  498. if (!typedef_resolve_cache) {
  499. typedef_resolve_cache = NewHash();
  500. }
  501. r = Getattr(typedef_resolve_cache, t);
  502. if (r) {
  503. resolved_scope = Getmeta(r, "scope");
  504. return Copy(r);
  505. }
  506. #endif
  507. base = SwigType_base(t);
  508. #ifdef SWIG_DEBUG
  509. Printf(stdout, "base = '%s' t='%s'\n", base, t);
  510. #endif
  511. if (SwigType_issimple(base)) {
  512. s = current_scope;
  513. ttab = current_typetab;
  514. if (strncmp(Char(base), "::", 2) == 0) {
  515. s = global_scope;
  516. ttab = Getattr(s, "typetab");
  517. Delitem(base, 0);
  518. Delitem(base, 0);
  519. }
  520. /* Do a quick check in the local scope */
  521. type = Getattr(ttab, base);
  522. if (type) {
  523. resolved_scope = s;
  524. }
  525. if (!type) {
  526. /* Didn't find in this scope. We need to do a little more searching */
  527. if (Swig_scopename_check(base)) {
  528. /* A qualified name. */
  529. Swig_scopename_split(base, &nameprefix, &namebase);
  530. #ifdef SWIG_DEBUG
  531. Printf(stdout, "nameprefix = '%s'\n", nameprefix);
  532. #endif
  533. if (nameprefix) {
  534. /* Name had a prefix on it. See if we can locate the proper scope for it */
  535. s = SwigType_find_scope(s, nameprefix);
  536. /* Couldn't locate a scope for the type. */
  537. if (!s) {
  538. Delete(base);
  539. Delete(namebase);
  540. Delete(nameprefix);
  541. r = 0;
  542. goto return_result;
  543. }
  544. /* Try to locate the name starting in the scope */
  545. #ifdef SWIG_DEBUG
  546. Printf(stdout, "namebase = '%s'\n", namebase);
  547. #endif
  548. type = typedef_resolve(s, namebase);
  549. if (type) {
  550. /* we need to look for the resolved type, this will also
  551. fix the resolved_scope if 'type' and 'namebase' are
  552. declared in different scopes */
  553. String *rtype = 0;
  554. rtype = typedef_resolve(resolved_scope, type);
  555. if (rtype)
  556. type = rtype;
  557. }
  558. #ifdef SWIG_DEBUG
  559. Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type);
  560. #endif
  561. if ((type) && (!Swig_scopename_check(type)) && resolved_scope) {
  562. Typetab *rtab = resolved_scope;
  563. String *qname = Getattr(resolved_scope, "qname");
  564. /* If qualified *and* the typename is defined from the resolved scope, we qualify */
  565. if ((qname) && typedef_resolve(resolved_scope, type)) {
  566. type = Copy(type);
  567. Insert(type, 0, "::");
  568. Insert(type, 0, qname);
  569. #ifdef SWIG_DEBUG
  570. Printf(stdout, "qual %s \n", type);
  571. #endif
  572. newtype = 1;
  573. }
  574. resolved_scope = rtab;
  575. }
  576. } else {
  577. /* Name is unqualified. */
  578. type = typedef_resolve(s, base);
  579. }
  580. } else {
  581. /* Name is unqualified. */
  582. type = typedef_resolve(s, base);
  583. }
  584. }
  585. if (type && (Equal(base, type))) {
  586. if (newtype)
  587. Delete(type);
  588. Delete(base);
  589. Delete(namebase);
  590. Delete(nameprefix);
  591. r = 0;
  592. goto return_result;
  593. }
  594. /* If the type is a template, and no typedef was found, we need to check the
  595. template arguments one by one to see if they can be resolved. */
  596. if (!type && SwigType_istemplate(base)) {
  597. List *tparms;
  598. String *suffix;
  599. int i, sz;
  600. int rep = 0;
  601. type = SwigType_templateprefix(base);
  602. newtype = 1;
  603. suffix = SwigType_templatesuffix(base);
  604. Append(type, "<(");
  605. tparms = SwigType_parmlist(base);
  606. sz = Len(tparms);
  607. for (i = 0; i < sz; i++) {
  608. SwigType *tpr;
  609. SwigType *tp = Getitem(tparms, i);
  610. if (!rep) {
  611. tpr = SwigType_typedef_resolve(tp);
  612. } else {
  613. tpr = 0;
  614. }
  615. if (tpr) {
  616. Append(type, tpr);
  617. Delete(tpr);
  618. rep = 1;
  619. } else {
  620. Append(type, tp);
  621. }
  622. if ((i + 1) < sz)
  623. Append(type, ",");
  624. }
  625. Append(type, ")>");
  626. Append(type, suffix);
  627. Delete(suffix);
  628. Delete(tparms);
  629. if (!rep) {
  630. Delete(type);
  631. type = 0;
  632. }
  633. }
  634. if (namebase)
  635. Delete(namebase);
  636. if (nameprefix)
  637. Delete(nameprefix);
  638. } else {
  639. if (SwigType_isfunction(base)) {
  640. List *parms;
  641. int i, sz;
  642. int rep = 0;
  643. type = NewString("f(");
  644. newtype = 1;
  645. parms = SwigType_parmlist(base);
  646. sz = Len(parms);
  647. for (i = 0; i < sz; i++) {
  648. SwigType *tpr;
  649. SwigType *tp = Getitem(parms, i);
  650. if (!rep) {
  651. tpr = SwigType_typedef_resolve(tp);
  652. } else {
  653. tpr = 0;
  654. }
  655. if (tpr) {
  656. Append(type, tpr);
  657. Delete(tpr);
  658. rep = 1;
  659. } else {
  660. Append(type, tp);
  661. }
  662. if ((i + 1) < sz)
  663. Append(type, ",");
  664. }
  665. Append(type, ").");
  666. Delete(parms);
  667. if (!rep) {
  668. Delete(type);
  669. type = 0;
  670. }
  671. } else if (SwigType_ismemberpointer(base)) {
  672. String *rt;
  673. String *mtype = SwigType_parm(base);
  674. rt = SwigType_typedef_resolve(mtype);
  675. if (rt) {
  676. type = NewStringf("m(%s).", rt);
  677. newtype = 1;
  678. Delete(rt);
  679. }
  680. Delete(mtype);
  681. } else {
  682. type = 0;
  683. }
  684. }
  685. r = SwigType_prefix(t);
  686. if (!type) {
  687. if (r && Len(r)) {
  688. char *cr = Char(r);
  689. if ((strstr(cr, "f(") || (strstr(cr, "m(")))) {
  690. SwigType *rt = SwigType_typedef_resolve(r);
  691. if (rt) {
  692. Delete(r);
  693. Append(rt, base);
  694. Delete(base);
  695. r = rt;
  696. goto return_result;
  697. }
  698. }
  699. }
  700. Delete(r);
  701. Delete(base);
  702. r = 0;
  703. goto return_result;
  704. }
  705. Delete(base);
  706. Append(r, type);
  707. if (newtype) {
  708. Delete(type);
  709. }
  710. return_result:
  711. #ifdef SWIG_TYPEDEF_RESOLVE_CACHE
  712. {
  713. String *key = NewString(t);
  714. if (r) {
  715. SwigType *r1;
  716. Setattr(typedef_resolve_cache, key, r);
  717. Setmeta(r, "scope", resolved_scope);
  718. r1 = Copy(r);
  719. Delete(r);
  720. r = r1;
  721. }
  722. Delete(key);
  723. }
  724. #endif
  725. return r;
  726. }
  727. /* -----------------------------------------------------------------------------
  728. * SwigType_typedef_resolve_all()
  729. *
  730. * Fully resolve a type down to its most basic datatype
  731. * ----------------------------------------------------------------------------- */
  732. SwigType *SwigType_typedef_resolve_all(SwigType *t) {
  733. SwigType *n;
  734. SwigType *r;
  735. /* Check to see if the typedef resolve has been done before by checking the cache */
  736. if (!typedef_all_cache) {
  737. typedef_all_cache = NewHash();
  738. }
  739. r = Getattr(typedef_all_cache, t);
  740. if (r) {
  741. return Copy(r);
  742. }
  743. /* Recursively resolve the typedef */
  744. r = NewString(t);
  745. while ((n = SwigType_typedef_resolve(r))) {
  746. Delete(r);
  747. r = n;
  748. }
  749. /* Add the typedef to the cache for next time it is looked up */
  750. {
  751. String *key;
  752. SwigType *rr = Copy(r);
  753. key = NewString(t);
  754. Setattr(typedef_all_cache, key, rr);
  755. Delete(key);
  756. Delete(rr);
  757. }
  758. return r;
  759. }
  760. /* -----------------------------------------------------------------------------
  761. * SwigType_typedef_qualified()
  762. *
  763. * Given a type declaration, this function tries to fully qualify it according to
  764. * typedef scope rules.
  765. * If the unary scope operator (::) is used as a prefix to the type to denote global
  766. * scope, it is left in place.
  767. * ----------------------------------------------------------------------------- */
  768. SwigType *SwigType_typedef_qualified(SwigType *t) {
  769. List *elements;
  770. String *result;
  771. int i, len;
  772. if (!typedef_qualified_cache)
  773. typedef_qualified_cache = NewHash();
  774. result = Getattr(typedef_qualified_cache, t);
  775. if (result) {
  776. String *rc = Copy(result);
  777. return rc;
  778. }
  779. result = NewStringEmpty();
  780. elements = SwigType_split(t);
  781. len = Len(elements);
  782. for (i = 0; i < len; i++) {
  783. String *ty = 0;
  784. String *e = Getitem(elements, i);
  785. if (SwigType_issimple(e)) {
  786. if (!SwigType_istemplate(e)) {
  787. String *isenum = 0;
  788. if (SwigType_isenum(e)) {
  789. isenum = NewString("enum ");
  790. ty = NewString(Char(e) + 5);
  791. e = ty;
  792. }
  793. resolved_scope = 0;
  794. if (typedef_resolve(current_scope, e)) {
  795. /* resolved_scope contains the scope that actually resolved the symbol */
  796. String *qname = Getattr(resolved_scope, "qname");
  797. if (qname) {
  798. Insert(e, 0, "::");
  799. Insert(e, 0, qname);
  800. }
  801. } else {
  802. if (Swig_scopename_check(e)) {
  803. String *qlast;
  804. String *qname;
  805. Swig_scopename_split(e, &qname, &qlast);
  806. if (qname) {
  807. String *tqname = SwigType_typedef_qualified(qname);
  808. Clear(e);
  809. Printf(e, "%s::%s", tqname, qlast);
  810. Delete(qname);
  811. Delete(tqname);
  812. }
  813. Delete(qlast);
  814. /* Automatic template instantiation might go here??? */
  815. } else {
  816. /* It's a bare name. It's entirely possible, that the
  817. name is part of a namespace. We'll check this by unrolling
  818. out of the current scope */
  819. Typetab *cs = current_scope;
  820. while (cs) {
  821. String *qs = SwigType_scope_name(cs);
  822. if (Len(qs)) {
  823. Append(qs, "::");
  824. }
  825. Append(qs, e);
  826. if (Getattr(scopes, qs)) {
  827. Clear(e);
  828. Append(e, qs);
  829. Delete(qs);
  830. break;
  831. }
  832. Delete(qs);
  833. cs = Getattr(cs, "parent");
  834. }
  835. }
  836. }
  837. if (isenum) {
  838. Insert(e, 0, isenum);
  839. Delete(isenum);
  840. }
  841. } else {
  842. /* Template. We need to qualify template parameters as well as the template itself */
  843. String *tprefix, *qprefix;
  844. String *tsuffix;
  845. Iterator pi;
  846. Parm *p;
  847. List *parms;
  848. ty = Swig_symbol_template_deftype(e, current_symtab);
  849. e = ty;
  850. parms = SwigType_parmlist(e);
  851. tprefix = SwigType_templateprefix(e);
  852. tsuffix = SwigType_templatesuffix(e);
  853. qprefix = SwigType_typedef_qualified(tprefix);
  854. Append(qprefix, "<(");
  855. pi = First(parms);
  856. while ((p = pi.item)) {
  857. String *qt = SwigType_typedef_qualified(p);
  858. if (Equal(qt, p)) { /* && (!Swig_scopename_check(qt))) */
  859. /* No change in value. It is entirely possible that the parameter is an integer value.
  860. If there is a symbol table associated with this scope, we're going to check for this */
  861. if (current_symtab) {
  862. Node *lastnode = 0;
  863. String *value = Copy(p);
  864. while (1) {
  865. Node *n = Swig_symbol_clookup(value, current_symtab);
  866. if (n == lastnode)
  867. break;
  868. lastnode = n;
  869. if (n) {
  870. char *ntype = Char(nodeType(n));
  871. if (strcmp(ntype, "enumitem") == 0) {
  872. /* An enum item. Generate a fully qualified name */
  873. String *qn = Swig_symbol_qualified(n);
  874. if (Len(qn)) {
  875. Append(qn, "::");
  876. Append(qn, Getattr(n, "name"));
  877. Delete(value);
  878. value = qn;
  879. continue;
  880. } else {
  881. Delete(qn);
  882. break;
  883. }
  884. } else if ((strcmp(ntype, "cdecl") == 0) && (Getattr(n, "value"))) {
  885. Delete(value);
  886. value = Copy(Getattr(n, "value"));
  887. continue;
  888. }
  889. }
  890. break;
  891. }
  892. Append(qprefix, value);
  893. Delete(value);
  894. } else {
  895. Append(qprefix, p);
  896. }
  897. } else {
  898. Append(qprefix, qt);
  899. }
  900. Delete(qt);
  901. pi = Next(pi);
  902. if (pi.item) {
  903. Append(qprefix, ",");
  904. }
  905. }
  906. Append(qprefix, ")>");
  907. Append(qprefix, tsuffix);
  908. Delete(tsuffix);
  909. Clear(e);
  910. Append(e, qprefix);
  911. Delete(tprefix);
  912. Delete(qprefix);
  913. Delete(parms);
  914. }
  915. Append(result, e);
  916. Delete(ty);
  917. } else if (SwigType_isfunction(e)) {
  918. List *parms = SwigType_parmlist(e);
  919. String *s = NewString("f(");
  920. Iterator pi;
  921. pi = First(parms);
  922. while (pi.item) {
  923. String *pq = SwigType_typedef_qualified(pi.item);
  924. Append(s, pq);
  925. Delete(pq);
  926. pi = Next(pi);
  927. if (pi.item) {
  928. Append(s, ",");
  929. }
  930. }
  931. Append(s, ").");
  932. Append(result, s);
  933. Delete(s);
  934. Delete(parms);
  935. } else if (SwigType_isarray(e)) {
  936. String *ndim;
  937. String *dim = SwigType_parm(e);
  938. ndim = Swig_symbol_string_qualify(dim, 0);
  939. Printf(result, "a(%s).", ndim);
  940. Delete(dim);
  941. Delete(ndim);
  942. } else {
  943. Append(result, e);
  944. }
  945. }
  946. Delete(elements);
  947. {
  948. String *key, *cresult;
  949. key = NewString(t);
  950. cresult = NewString(result);
  951. Setattr(typedef_qualified_cache, key, cresult);
  952. Delete(key);
  953. Delete(cresult);
  954. }
  955. return result;
  956. }
  957. /* -----------------------------------------------------------------------------
  958. * SwigType_istypedef()
  959. *
  960. * Checks a typename to see if it is a typedef.
  961. * ----------------------------------------------------------------------------- */
  962. int SwigType_istypedef(SwigType *t) {
  963. String *type;
  964. type = SwigType_typedef_resolve(t);
  965. if (type) {
  966. Delete(type);
  967. return 1;
  968. } else {
  969. return 0;
  970. }
  971. }
  972. /* -----------------------------------------------------------------------------
  973. * SwigType_typedef_using()
  974. *
  975. * Processes a 'using' declaration to import types from one scope into another.
  976. * Name is a qualified name like A::B.
  977. * ----------------------------------------------------------------------------- */
  978. int SwigType_typedef_using(const_String_or_char_ptr name) {
  979. String *base;
  980. String *td;
  981. String *prefix;
  982. Typetab *s;
  983. Typetab *tt = 0;
  984. String *defined_name = 0;
  985. /* Printf(stdout,"using %s\n", name); */
  986. if (!Swig_scopename_check(name))
  987. return -1; /* Not properly qualified */
  988. base = Swig_scopename_last(name);
  989. /* See if the base is already defined in this scope */
  990. if (Getattr(current_typetab, base)) {
  991. Delete(base);
  992. return -1;
  993. }
  994. /* See if the using name is a scope */
  995. /* tt = SwigType_find_scope(current_scope,name);
  996. Printf(stdout,"tt = %x, name = '%s'\n", tt, name); */
  997. /* We set up a typedef B --> A::B */
  998. Setattr(current_typetab, base, name);
  999. /* Find the scope name where the symbol is defined */
  1000. td = SwigType_typedef_resolve(name);
  1001. /* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */
  1002. if (resolved_scope) {
  1003. defined_name = Getattr(resolved_scope, "qname");
  1004. if (defined_name) {
  1005. defined_name = Copy(defined_name);
  1006. Append(defined_name, "::");
  1007. Append(defined_name, base);
  1008. /* Printf(stdout,"defined_name = '%s'\n", defined_name); */
  1009. tt = SwigType_find_scope(current_scope, defined_name);
  1010. }
  1011. }
  1012. if (td)
  1013. Delete(td);
  1014. /* Figure out the scope the using directive refers to */
  1015. {
  1016. prefix = Swig_scopename_prefix(name);
  1017. if (prefix) {
  1018. s = SwigType_find_scope(current_scope, prefix);
  1019. if (s) {
  1020. Hash *ttab = Getattr(s, "typetab");
  1021. if (!Getattr(ttab, base) && defined_name) {
  1022. Setattr(ttab, base, defined_name);
  1023. }
  1024. }
  1025. }
  1026. }
  1027. if (tt) {
  1028. /* Using directive had its own scope. We need to create a new scope for it */
  1029. SwigType_new_scope(base);
  1030. SwigType_inherit_scope(tt);
  1031. SwigType_pop_scope();
  1032. }
  1033. if (defined_name)
  1034. Delete(defined_name);
  1035. Delete(prefix);
  1036. Delete(base);
  1037. return 0;
  1038. }
  1039. /* -----------------------------------------------------------------------------
  1040. * SwigType_isclass()
  1041. *
  1042. * Determines if a type defines a class or not. A class is defined by
  1043. * its type-table entry maps to itself. Note: a pointer to a class is not
  1044. * a class.
  1045. * ----------------------------------------------------------------------------- */
  1046. int SwigType_isclass(SwigType *t) {
  1047. SwigType *qty, *qtys;
  1048. int isclass = 0;
  1049. qty = SwigType_typedef_resolve_all(t);
  1050. qtys = SwigType_strip_qualifiers(qty);
  1051. if (SwigType_issimple(qtys)) {
  1052. String *td = SwigType_typedef_resolve(qtys);
  1053. if (td) {
  1054. Delete(td);
  1055. }
  1056. if (resolved_scope) {
  1057. isclass = 1;
  1058. }
  1059. /* Hmmm. Not a class. If a template, it might be uninstantiated */
  1060. if (!isclass) {
  1061. String *tp = SwigType_istemplate_templateprefix(qtys);
  1062. if (tp && Strcmp(tp, t) != 0) {
  1063. isclass = SwigType_isclass(tp);
  1064. }
  1065. Delete(tp);
  1066. }
  1067. }
  1068. Delete(qty);
  1069. Delete(qtys);
  1070. return isclass;
  1071. }
  1072. /* -----------------------------------------------------------------------------
  1073. * SwigType_type()
  1074. *
  1075. * Returns an integer code describing the datatype. This is only used for
  1076. * compatibility with SWIG1.1 language modules and is likely to go away once
  1077. * everything is based on typemaps.
  1078. * ----------------------------------------------------------------------------- */
  1079. int SwigType_type(SwigType *t) {
  1080. char *c;
  1081. /* Check for the obvious stuff */
  1082. c = Char(t);
  1083. if (strncmp(c, "p.", 2) == 0) {
  1084. if (SwigType_type(c + 2) == T_CHAR)
  1085. return T_STRING;
  1086. else
  1087. return T_POINTER;
  1088. }
  1089. if (strncmp(c, "a(", 2) == 0)
  1090. return T_ARRAY;
  1091. if (strncmp(c, "r.", 2) == 0)
  1092. return T_REFERENCE;
  1093. if (strncmp(c, "m(", 2) == 0)
  1094. return T_MPOINTER;
  1095. if (strncmp(c, "q(", 2) == 0) {
  1096. while (*c && (*c != '.'))
  1097. c++;
  1098. if (*c)
  1099. return SwigType_type(c + 1);
  1100. return T_ERROR;
  1101. }
  1102. if (strncmp(c, "f(", 2) == 0)
  1103. return T_FUNCTION;
  1104. /* Look for basic types */
  1105. if (strcmp(c, "int") == 0)
  1106. return T_INT;
  1107. if (strcmp(c, "long") == 0)
  1108. return T_LONG;
  1109. if (strcmp(c, "short") == 0)
  1110. return T_SHORT;
  1111. if (strcmp(c, "unsigned") == 0)
  1112. return T_UINT;
  1113. if (strcmp(c, "unsigned short") == 0)
  1114. return T_USHORT;
  1115. if (strcmp(c, "unsigned long") == 0)
  1116. return T_ULONG;
  1117. if (strcmp(c, "unsigned int") == 0)
  1118. return T_UINT;
  1119. if (strcmp(c, "char") == 0)
  1120. return T_CHAR;
  1121. if (strcmp(c, "signed char") == 0)
  1122. return T_SCHAR;
  1123. if (strcmp(c, "unsigned char") == 0)
  1124. return T_UCHAR;
  1125. if (strcmp(c, "float") == 0)
  1126. return T_FLOAT;
  1127. if (strcmp(c, "double") == 0)
  1128. return T_DOUBLE;
  1129. if (strcmp(c, "long double") == 0)
  1130. return T_LONGDOUBLE;
  1131. if (!cparse_cplusplus && (strcmp(c, "float complex") == 0))
  1132. return T_FLTCPLX;
  1133. if (!cparse_cplusplus && (strcmp(c, "double complex") == 0))
  1134. return T_DBLCPLX;
  1135. if (!cparse_cplusplus && (strcmp(c, "complex") == 0))
  1136. return T_COMPLEX;
  1137. if (strcmp(c, "void") == 0)
  1138. return T_VOID;
  1139. if (strcmp(c, "bool") == 0)
  1140. return T_BOOL;
  1141. if (strcmp(c, "long long") == 0)
  1142. return T_LONGLONG;
  1143. if (strcmp(c, "unsigned long long") == 0)
  1144. return T_ULONGLONG;
  1145. if (strncmp(c, "enum ", 5) == 0)
  1146. return T_INT;
  1147. if (strcmp(c, "v(...)") == 0)
  1148. return T_VARARGS;
  1149. /* Hmmm. Unknown type */
  1150. if (SwigType_istypedef(t)) {
  1151. int r;
  1152. SwigType *nt = SwigType_typedef_resolve(t);
  1153. r = SwigType_type(nt);
  1154. Delete(nt);
  1155. return r;
  1156. }
  1157. return T_USER;
  1158. }
  1159. /* -----------------------------------------------------------------------------
  1160. * SwigType_alttype()
  1161. *
  1162. * Returns the alternative value type needed in C++ for class value
  1163. * types. When swig is not sure about using a plain $ltype value,
  1164. * since the class doesn't have a default constructor, or it can't be
  1165. * assigned, you will get back 'SwigValueWrapper<type >'.
  1166. *
  1167. * This is the default behavior unless:
  1168. *
  1169. * 1.- swig detects a default_constructor and 'setallocate:default_constructor'
  1170. * attribute.
  1171. *
  1172. * 2.- swig doesn't mark 'type' as non-assignable.
  1173. *
  1174. * 3.- the user specify that the value wrapper is not needed by using
  1175. * the %feature("novaluewrapper"), in that case the user need to type
  1176. *
  1177. * %feature("novaluewrapper") MyOpaqueClass;
  1178. * class MyOpaqueClass;
  1179. *
  1180. * Users can also force the use of the value wrapper by using the
  1181. * %feature("valuewrapper").
  1182. * ----------------------------------------------------------------------------- */
  1183. SwigType *SwigType_alttype(SwigType *t, int local_tmap) {
  1184. Node *n;
  1185. SwigType *w = 0;
  1186. int use_wrapper = 0;
  1187. SwigType *td = 0;
  1188. if (!cparse_cplusplus)
  1189. return 0;
  1190. if (value_wrapper_mode == 0) {
  1191. /* old partial use of SwigValueTypes, it can fail for opaque types */
  1192. if (local_tmap)
  1193. return 0;
  1194. if (SwigType_isclass(t)) {
  1195. SwigType *ftd = SwigType_typedef_resolve_all(t);
  1196. td = SwigType_strip_qualifiers(ftd);
  1197. Delete(ftd);
  1198. n = Swig_symbol_clookup(td, 0);
  1199. if (n) {
  1200. if (GetFlag(n, "feature:valuewrapper")) {
  1201. use_wrapper = 1;
  1202. } else {
  1203. if (Checkattr(n, "nodeType", "class")
  1204. && (!Getattr(n, "allocate:default_constructor")
  1205. || (Getattr(n, "allocate:noassign")))) {
  1206. use_wrapper = !GetFlag(n, "feature:novaluewrapper") || GetFlag(n, "feature:nodefault");
  1207. }
  1208. }
  1209. } else {
  1210. if (SwigType_issimple(td) && SwigType_istemplate(td)) {
  1211. use_wrapper = !n || !GetFlag(n, "feature:novaluewrapper");
  1212. }
  1213. }
  1214. }
  1215. } else {
  1216. /* safe use of SwigValueTypes, it can fail with some typemaps */
  1217. SwigType *ftd = SwigType_typedef_resolve_all(t);
  1218. td = SwigType_strip_qualifiers(ftd);
  1219. Delete(ftd);
  1220. if (SwigType_type(td) == T_USER) {
  1221. use_wrapper = 1;
  1222. n = Swig_symbol_clookup(td, 0);
  1223. if (n) {
  1224. if ((Checkattr(n, "nodeType", "class")
  1225. && !Getattr(n, "allocate:noassign")
  1226. && (Getattr(n, "allocate:default_constructor")))
  1227. || (GetFlag(n, "feature:novaluewrapper"))) {
  1228. use_wrapper = GetFlag(n, "feature:valuewrapper");
  1229. }
  1230. }
  1231. }
  1232. }
  1233. if (use_wrapper) {
  1234. /* Need a space before the type in case it starts "::" (since the <:
  1235. * token is a digraph for [ in C++. Also need a space after the
  1236. * type in case it ends with ">" since then we form the token ">>".
  1237. */
  1238. w = NewStringf("SwigValueWrapper< %s >", td);
  1239. }
  1240. Delete(td);
  1241. return w;
  1242. }
  1243. /* ----------------------------------------------------------------------------
  1244. * * * * WARNING * * * ***
  1245. * ***
  1246. * Don't even think about modifying anything below this line unless you ***
  1247. * are completely on top of *EVERY* subtle aspect of the C++ type system ***
  1248. * and you are prepared to suffer endless hours of agony trying to ***
  1249. * debug the SWIG run-time type checker after you break it. ***
  1250. * ------------------------------------------------------------------------- */
  1251. /* -----------------------------------------------------------------------------
  1252. * SwigType_remember()
  1253. *
  1254. * This function "remembers" a datatype that was used during wrapper code generation
  1255. * so that a type-checking table can be generated later on. It is up to the language
  1256. * modules to actually call this function--it is not done automatically.
  1257. *
  1258. * Type tracking is managed through two separate hash tables. The hash 'r_mangled'
  1259. * is mapping between mangled type names (used in the target language) and
  1260. * fully-resolved C datatypes used in the source input. The second hash 'r_resolved'
  1261. * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled
  1262. * names in the scripting languages. For example, consider the following set of
  1263. * typedef declarations:
  1264. *
  1265. * typedef double Real;
  1266. * typedef double Float;
  1267. * typedef double Point[3];
  1268. *
  1269. * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and
  1270. * 'Point' were used in an interface file and "remembered" using this function.
  1271. * The hash tables would look like this:
  1272. *
  1273. * r_mangled {
  1274. * _p_double : [ p.double, a(3).double ]
  1275. * _p_Real : [ p.double ]
  1276. * _p_Float : [ p.double ]
  1277. * _Point : [ a(3).double ]
  1278. *
  1279. * r_resolved {
  1280. * p.double : [ _p_double, _p_Real, _p_Float ]
  1281. * a(3).double : [ _p_double, _Point ]
  1282. * }
  1283. *
  1284. * Together these two hash tables can be used to determine type-equivalency between
  1285. * mangled typenames. To do this, we view the two hash tables as a large graph and
  1286. * compute the transitive closure.
  1287. * ----------------------------------------------------------------------------- */
  1288. static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */
  1289. static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */
  1290. static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */
  1291. static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data */
  1292. static Hash *r_mangleddata = 0; /* Hash mapping mangled types to client data */
  1293. static Hash *r_remembered = 0; /* Hash of types we remembered already */
  1294. static void (*r_tracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
  1295. void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata) {
  1296. if (!r_mangleddata) {
  1297. r_mangleddata = NewHash();
  1298. }
  1299. Setattr(r_mangleddata, mangled, clientdata);
  1300. }
  1301. void SwigType_remember_clientdata(SwigType *t, const_String_or_char_ptr clientdata) {
  1302. String *mt;
  1303. SwigType *lt;
  1304. Hash *h;
  1305. SwigType *fr;
  1306. SwigType *qr;
  1307. String *tkey;
  1308. String *cd;
  1309. Hash *lthash;
  1310. if (!r_mangled) {
  1311. r_mangled = NewHash();
  1312. r_resolved = NewHash();
  1313. r_ltype = NewHash();
  1314. r_clientdata = NewHash();
  1315. r_remembered = NewHash();
  1316. }
  1317. {
  1318. String *last;
  1319. last = Getattr(r_remembered, t);
  1320. if (last && (Cmp(last, clientdata) == 0))
  1321. return;
  1322. }
  1323. tkey = Copy(t);
  1324. cd = clientdata ? NewString(clientdata) : NewStringEmpty();
  1325. Setattr(r_remembered, tkey, cd);
  1326. Delete(tkey);
  1327. Delete(cd);
  1328. mt = SwigType_manglestr(t); /* Create mangled string */
  1329. if (r_tracefunc) {
  1330. (*r_tracefunc) (t, mt, (String *) clientdata);
  1331. }
  1332. if (SwigType_istypedef(t)) {
  1333. lt = Copy(t);
  1334. } else {
  1335. lt = SwigType_ltype(t);
  1336. }
  1337. lthash = Getattr(r_ltype, mt);
  1338. if (!lthash) {
  1339. lthash = NewHash();
  1340. Setattr(r_ltype, mt, lthash);
  1341. }
  1342. Setattr(lthash, lt, "1");
  1343. Delete(lt);
  1344. fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */
  1345. qr = SwigType_typedef_qualified(fr);
  1346. Delete(fr);
  1347. /* Added to deal with possible table bug */
  1348. fr = SwigType_strip_qualifiers(qr);
  1349. Delete(qr);
  1350. /*Printf(stdout,"t = '%s'\n", t);
  1351. Printf(stdout,"fr= '%s'\n\n", fr); */
  1352. if (t) {
  1353. char *ct = Char(t);
  1354. if (strchr(ct, '<') && !(strstr(ct, "<("))) {
  1355. Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t);
  1356. assert(0);
  1357. }
  1358. }
  1359. h = Getattr(r_mangled, mt);
  1360. if (!h) {
  1361. h = NewHash();
  1362. Setattr(r_mangled, mt, h);
  1363. Delete(h);
  1364. }
  1365. Setattr(h, fr, mt);
  1366. h = Getattr(r_resolved, fr);
  1367. if (!h) {
  1368. h = NewHash();
  1369. Setattr(r_resolved, fr, h);
  1370. Delete(h);
  1371. }
  1372. Setattr(h, mt, fr);
  1373. if (clientdata) {
  1374. String *cd = Getattr(r_clientdata, fr);
  1375. if (cd) {
  1376. if (Strcmp(clientdata, cd) != 0) {
  1377. Printf(stderr, "*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr, 0));
  1378. Printf(stderr, "*** '%s' != '%s'\n", clientdata, cd);
  1379. assert(0);
  1380. }
  1381. } else {
  1382. String *cstr = NewString(clientdata);
  1383. Setattr(r_clientdata, fr, cstr);
  1384. Delete(cstr);
  1385. }
  1386. }
  1387. /* If the remembered type is a reference, we also remember the pointer version.
  1388. This is to prevent odd problems with mixing pointers and references--especially
  1389. when different functions are using different typenames (via typedef). */
  1390. if (SwigType_isreference(t)) {
  1391. SwigType *tt = Copy(t);
  1392. SwigType_del_reference(tt);
  1393. SwigType_add_pointer(tt);
  1394. SwigType_remember_clientdata(tt, clientdata);
  1395. }
  1396. }
  1397. void SwigType_remember(SwigType *ty) {
  1398. SwigType_remember_clientdata(ty, 0);
  1399. }
  1400. void (*SwigType_remember_trace(void (*tf) (SwigType *, String *, String *))) (SwigType *, String *, String *) {
  1401. void (*o) (SwigType *, String *, String *) = r_tracefunc;
  1402. r_tracefunc = tf;
  1403. return o;
  1404. }
  1405. /* -----------------------------------------------------------------------------
  1406. * SwigType_equivalent_mangle()
  1407. *
  1408. * Return a list of all of the mangled typenames that are equivalent to another
  1409. * mangled name. This works as follows: For each fully qualified C datatype
  1410. * in the r_mangled hash entry, we collect all of the mangled names from the
  1411. * r_resolved hash and combine them together in a list (removing duplicate entries).
  1412. * ----------------------------------------------------------------------------- */
  1413. List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) {
  1414. List *l;
  1415. Hash *h;
  1416. Hash *ch;
  1417. Hash *mh;
  1418. if (found) {
  1419. h = found;
  1420. } else {
  1421. h = NewHash();
  1422. }
  1423. if (checked) {
  1424. ch = checked;
  1425. } else {
  1426. ch = NewHash();
  1427. }
  1428. if (Getattr(ch, ms))
  1429. goto check_exit; /* Already checked this type */
  1430. Setattr(h, ms, "1");
  1431. Setattr(ch, ms, "1");
  1432. mh = Getattr(r_mangled, ms);
  1433. if (mh) {
  1434. Iterator ki;
  1435. ki = First(mh);
  1436. while (ki.key) {
  1437. Hash *rh;
  1438. if (Getattr(ch, ki.key)) {
  1439. ki = Next(ki);
  1440. continue;
  1441. }
  1442. Setattr(ch, ki.key, "1");
  1443. rh = Getattr(r_resolved, ki.key);
  1444. if (rh) {
  1445. Iterator rk;
  1446. rk = First(rh);
  1447. while (rk.key) {
  1448. Setattr(h, rk.key, "1");
  1449. SwigType_equivalent_mangle(rk.key, ch, h);
  1450. rk = Next(rk);
  1451. }
  1452. }
  1453. ki = Next(ki);
  1454. }
  1455. }
  1456. check_exit:
  1457. if (!found) {
  1458. l = Keys(h);
  1459. Delete(h);
  1460. Delete(ch);
  1461. return l;
  1462. } else {
  1463. return 0;
  1464. }
  1465. }
  1466. /* -----------------------------------------------------------------------------
  1467. * SwigType_clientdata_collect()
  1468. *
  1469. * Returns the clientdata field for a mangled type-string.
  1470. * ----------------------------------------------------------------------------- */
  1471. static
  1472. String *SwigType_clientdata_collect(String *ms) {
  1473. Hash *mh;
  1474. String *clientdata = 0;
  1475. if (r_mangleddata) {
  1476. clientdata = Getattr(r_mangleddata, ms);
  1477. if (clientdata)
  1478. return clientdata;
  1479. }
  1480. mh = Getattr(r_mangled, ms);
  1481. if (mh) {
  1482. Iterator ki;
  1483. ki = First(mh);
  1484. while (ki.key) {
  1485. clientdata = Getattr(r_clientdata, ki.key);
  1486. if (clientdata)
  1487. break;
  1488. ki = Next(ki);
  1489. }
  1490. }
  1491. return clientdata;
  1492. }
  1493. /* -----------------------------------------------------------------------------
  1494. * SwigType_inherit()
  1495. *
  1496. * Record information about inheritance. We keep a hash table that keeps
  1497. * a mapping between base classes and all of the classes that are derived
  1498. * from them.
  1499. *
  1500. * subclass is a hash that maps base-classes to all of the classes derived from them.
  1501. *
  1502. * derived - name of derived class
  1503. * base - name of base class
  1504. * cast - additional casting code when casting from derived to base
  1505. * conversioncode - if set, overrides the default code in the function when casting
  1506. * from derived to base
  1507. * ----------------------------------------------------------------------------- */
  1508. static Hash *subclass = 0;
  1509. static Hash *conversions = 0;
  1510. void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) {
  1511. Hash *h;
  1512. String *dd = 0;
  1513. String *bb = 0;
  1514. if (!subclass)
  1515. subclass = NewHash();
  1516. /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
  1517. if (SwigType_istemplate(derived)) {
  1518. String *ty = SwigType_typedef_resolve_all(derived);
  1519. dd = SwigType_typedef_qualified(ty);
  1520. derived = dd;
  1521. Delete(ty);
  1522. }
  1523. if (SwigType_istemplate(base)) {
  1524. String *ty = SwigType_typedef_resolve_all(base);
  1525. bb = SwigType_typedef_qualified(ty);
  1526. base = bb;
  1527. Delete(ty);
  1528. }
  1529. /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
  1530. h = Getattr(subclass, base);
  1531. if (!h) {
  1532. h = NewHash();
  1533. Setattr(subclass, base, h);
  1534. Delete(h);
  1535. }
  1536. if (!Getattr(h, derived)) {
  1537. Hash *c = NewHash();
  1538. if (cast)
  1539. Setattr(c, "cast", cast);
  1540. if (conversioncode)
  1541. Setattr(c, "convcode", conversioncode);
  1542. Setattr(h, derived, c);
  1543. Delete(c);
  1544. }
  1545. Delete(dd);
  1546. Delete(bb);
  1547. }
  1548. /* -----------------------------------------------------------------------------
  1549. * SwigType_issubtype()
  1550. *
  1551. * Determines if a t1 is a subtype of t2, ie, is t1 derived from t2
  1552. * ----------------------------------------------------------------------------- */
  1553. int SwigType_issubtype(SwigType *t1, SwigType *t2) {
  1554. SwigType *ft1, *ft2;
  1555. String *b1, *b2;
  1556. Hash *h;
  1557. int r = 0;
  1558. if (!subclass)
  1559. return 0;
  1560. ft1 = SwigType_typedef_resolve_all(t1);
  1561. ft2 = SwigType_typedef_resolve_all(t2);
  1562. b1 = SwigType_base(ft1);
  1563. b2 = SwigType_base(ft2);
  1564. h = Getattr(subclass, b2);
  1565. if (h) {
  1566. if (Getattr(h, b1)) {
  1567. r = 1;
  1568. }
  1569. }
  1570. Delete(ft1);
  1571. Delete(ft2);
  1572. Delete(b1);
  1573. Delete(b2);
  1574. /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */
  1575. return r;
  1576. }
  1577. /* -----------------------------------------------------------------------------
  1578. * SwigType_inherit_equiv()
  1579. *
  1580. * Modify the type table to handle C++ inheritance
  1581. * ----------------------------------------------------------------------------- */
  1582. void SwigType_inherit_equiv(File *out) {
  1583. String *ckey;
  1584. String *prefix, *base;
  1585. String *mprefix, *mkey;
  1586. Hash *sub;
  1587. Hash *rh;
  1588. List *rlist;
  1589. Iterator rk, bk, ck;
  1590. if (!conversions)
  1591. conversions = NewHash();
  1592. if (!subclass)
  1593. subclass = NewHash();
  1594. rk = First(r_resolved);
  1595. while (rk.key) {
  1596. /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */
  1597. base = SwigType_base(rk.key);
  1598. /* Check to see whether the base is recorded in the subclass table */
  1599. sub = Getattr(subclass, base);
  1600. Delete(base);
  1601. if (!sub) {
  1602. rk = Next(rk);
  1603. continue;
  1604. }
  1605. /* This type has subclasses. We now need to walk through these subtypes and generate pointer conversion functions */
  1606. rh = Getattr(r_resolved, rk.key);
  1607. rlist = NewList();
  1608. for (ck = First(rh); ck.key; ck = Next(ck)) {
  1609. Append(rlist, ck.key);
  1610. }
  1611. /* Printf(stdout,"rk.key = '%s'\n", rk.key);
  1612. Printf(stdout,"rh = %x '%s'\n", rh,rh); */
  1613. bk = First(sub);
  1614. while (bk.key) {
  1615. prefix = SwigType_prefix(rk.key);
  1616. Append(prefix, bk.key);
  1617. /* Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
  1618. mprefix = SwigType_manglestr(prefix);
  1619. Setattr(rh, mprefix, prefix);
  1620. mkey = SwigType_manglestr(rk.key);
  1621. ckey = NewStringf("%s+%s", mprefix, mkey);
  1622. if (!Getattr(conversions, ckey)) {
  1623. String *convname = NewStringf("%sTo%s", mprefix, mkey);
  1624. String *lkey = SwigType_lstr(rk.key, 0);
  1625. String *lprefix = SwigType_lstr(prefix, 0);
  1626. Hash *subhash = Getattr(sub, bk.key);
  1627. String *convcode = Getattr(subhash, "convcode");
  1628. if (convcode) {
  1629. char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */
  1630. String *fn = Copy(convcode);
  1631. Replaceall(fn, "$from", "x");
  1632. Printf(out, "static void *%s(void *x, int *%s) {", convname, newmemoryused ? "newmemory" : "SWIGUNUSEDPARM(newmemory)");
  1633. Printf(out, "%s", fn);
  1634. } else {
  1635. String *cast = Getattr(subhash, "cast");
  1636. Printf(out, "static void *%s(void *x, int *SWIGUNUSEDPARM(newmemory)) {", convnam