PageRenderTime 68ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 1ms

/trunk/Source/Modules/typepass.cxx

#
C++ | 1234 lines | 969 code | 115 blank | 150 comment | 257 complexity | 137171621df1b2b2f5de1d4adcbbe976 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  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. * typepass.cxx
  10. *
  11. * This module builds all of the internal type information by collecting
  12. * typedef declarations as well as registering classes, structures, and unions.
  13. * This information is needed to correctly handle shadow classes and other
  14. * advanced features. This phase of compilation is also used to perform
  15. * type-expansion. All types are fully qualified with namespace prefixes
  16. * and other information needed for compilation.
  17. * ----------------------------------------------------------------------------- */
  18. char cvsroot_typepass_cxx[] = "$Id: typepass.cxx 12953 2012-03-25 19:10:33Z wsfulton $";
  19. #include "swigmod.h"
  20. #include "cparse.h"
  21. struct normal_node {
  22. Symtab *symtab;
  23. Hash *typescope;
  24. List *normallist;
  25. normal_node *next;
  26. };
  27. static normal_node *patch_list = 0;
  28. /* Singleton class - all non-static methods in this class are private */
  29. class TypePass:private Dispatcher {
  30. Node *inclass;
  31. Node *module;
  32. int importmode;
  33. String *nsname;
  34. String *nssymname;
  35. Hash *classhash;
  36. List *normalize;
  37. TypePass() {
  38. }
  39. /* Normalize a type. Replaces type with fully qualified version */
  40. void normalize_type(SwigType *ty) {
  41. SwigType *qty;
  42. if (CPlusPlus) {
  43. Replaceall(ty, "struct ", "");
  44. Replaceall(ty, "union ", "");
  45. Replaceall(ty, "class ", "");
  46. }
  47. qty = SwigType_typedef_qualified(ty);
  48. /* Printf(stdout,"%s --> %s\n", ty, qty); */
  49. Clear(ty);
  50. Append(ty, qty);
  51. Delete(qty);
  52. }
  53. /* Normalize a parameter list */
  54. void normalize_parms(ParmList *p) {
  55. while (p) {
  56. SwigType *ty = Getattr(p, "type");
  57. normalize_type(ty);
  58. /* This is a check for a function type */
  59. {
  60. SwigType *qty = SwigType_typedef_resolve_all(ty);
  61. if (SwigType_isfunction(qty)) {
  62. SwigType_add_pointer(ty);
  63. }
  64. Delete(qty);
  65. }
  66. String *value = Getattr(p, "value");
  67. if (value) {
  68. Node *n = Swig_symbol_clookup(value, 0);
  69. if (n) {
  70. String *q = Swig_symbol_qualified(n);
  71. if (q && Len(q)) {
  72. String *vb = Swig_scopename_last(value);
  73. Clear(value);
  74. Printf(value, "%s::%s", SwigType_namestr(q), vb);
  75. Delete(q);
  76. }
  77. }
  78. }
  79. if (value && SwigType_istemplate(value)) {
  80. String *nv = SwigType_namestr(value);
  81. Setattr(p, "value", nv);
  82. }
  83. p = nextSibling(p);
  84. }
  85. }
  86. void normalize_later(ParmList *p) {
  87. while (p) {
  88. SwigType *ty = Getattr(p, "type");
  89. Append(normalize, ty);
  90. p = nextSibling(p);
  91. }
  92. }
  93. /* Walk through entries in normalize list and patch them up */
  94. void normalize_list() {
  95. Hash *currentsym = Swig_symbol_current();
  96. normal_node *nn = patch_list;
  97. normal_node *np;
  98. while (nn) {
  99. Swig_symbol_setscope(nn->symtab);
  100. SwigType_set_scope(nn->typescope);
  101. Iterator t;
  102. for (t = First(nn->normallist); t.item; t = Next(t)) {
  103. normalize_type(t.item);
  104. }
  105. Delete(nn->normallist);
  106. np = nn->next;
  107. delete(nn);
  108. nn = np;
  109. }
  110. Swig_symbol_setscope(currentsym);
  111. }
  112. /* generate C++ inheritance type-relationships */
  113. void cplus_inherit_types_impl(Node *first, Node *cls, String *clsname, const char *bases, const char *baselist, int ispublic, String *cast = 0) {
  114. if (first == cls)
  115. return; /* The Marcelo check */
  116. if (!cls)
  117. cls = first;
  118. List *alist = 0;
  119. List *ilist = Getattr(cls, bases);
  120. if (!ilist) {
  121. List *nlist = Getattr(cls, baselist);
  122. if (nlist) {
  123. int len = Len(nlist);
  124. int i;
  125. for (i = 0; i < len; i++) {
  126. Node *bcls = 0;
  127. int clsforward = 0;
  128. String *bname = Getitem(nlist, i);
  129. String *sname = bname;
  130. String *tname = 0;
  131. /* Try to locate the base class. We look in the symbol table and we chase
  132. typedef declarations to get to the base class if necessary */
  133. Symtab *st = Getattr(cls, "sym:symtab");
  134. if (SwigType_istemplate(bname)) {
  135. tname = SwigType_typedef_resolve_all(bname);
  136. sname = tname;
  137. }
  138. while (1) {
  139. String *qsname = SwigType_typedef_qualified(sname);
  140. bcls = Swig_symbol_clookup(qsname, st);
  141. Delete(qsname);
  142. if (bcls) {
  143. if (Strcmp(nodeType(bcls), "class") != 0) {
  144. /* Not a class. The symbol could be a typedef. */
  145. if (checkAttribute(bcls, "storage", "typedef")) {
  146. SwigType *decl = Getattr(bcls, "decl");
  147. if (!decl || !(Len(decl))) {
  148. sname = Getattr(bcls, "type");
  149. st = Getattr(bcls, "sym:symtab");
  150. if (SwigType_istemplate(sname)) {
  151. if (tname)
  152. Delete(tname);
  153. tname = SwigType_typedef_resolve_all(sname);
  154. sname = tname;
  155. }
  156. continue;
  157. }
  158. }
  159. if (Strcmp(nodeType(bcls), "classforward") != 0) {
  160. Swig_error(Getfile(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
  161. Swig_error(Getfile(bcls), Getline(bcls), "See definition of '%s'.\n", SwigType_namestr(bname));
  162. } else {
  163. Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bname), Getline(bname), "Base class '%s' is incomplete.\n", SwigType_namestr(bname));
  164. Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname));
  165. clsforward = 1;
  166. }
  167. bcls = 0;
  168. } else {
  169. if (Getattr(bcls, "typepass:visit")) {
  170. if (!ilist)
  171. ilist = alist = NewList();
  172. Append(ilist, bcls);
  173. } else {
  174. Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname));
  175. Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "'%s' must be defined before it is used as a base class.\n", SwigType_namestr(bname));
  176. }
  177. }
  178. }
  179. break;
  180. }
  181. if (tname)
  182. Delete(tname);
  183. if (!bcls) {
  184. if (!clsforward) {
  185. if (ispublic && !Getmeta(bname, "already_warned")) {
  186. Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
  187. if (Strchr(bname, '<')) {
  188. Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname));
  189. }
  190. Setmeta(bname, "already_warned", "1");
  191. }
  192. }
  193. SwigType_inherit(clsname, bname, cast, 0);
  194. }
  195. }
  196. }
  197. if (ilist) {
  198. Setattr(cls, bases, ilist);
  199. }
  200. }
  201. if (alist)
  202. Delete(alist);
  203. if (!ilist)
  204. return;
  205. int len = Len(ilist);
  206. int i;
  207. for (i = 0; i < len; i++) {
  208. Node *n = Getitem(ilist, i);
  209. String *bname = Getattr(n, "name");
  210. Node *bclass = n; /* Getattr(n,"class"); */
  211. Hash *scopes = Getattr(bclass, "typescope");
  212. SwigType_inherit(clsname, bname, cast, 0);
  213. String *smartptr = Getattr(first, "feature:smartptr");
  214. if (smartptr) {
  215. SwigType *smart = 0;
  216. SwigType *spt = Swig_cparse_type(smartptr);
  217. if (spt) {
  218. smart = SwigType_typedef_resolve_all(spt);
  219. Delete(spt);
  220. /* Record a (fake) inheritance relationship between smart pointer
  221. and smart pointer to base class, so that smart pointer upcasts
  222. are automatically generated. */
  223. SwigType *bsmart = Copy(smart);
  224. SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
  225. SwigType *rbname = SwigType_typedef_resolve_all(bname);
  226. Replaceall(bsmart, rclsname, rbname);
  227. Delete(rclsname);
  228. Delete(rbname);
  229. String *smartnamestr = SwigType_namestr(smart);
  230. String *bsmartnamestr = SwigType_namestr(bsmart);
  231. /* construct casting code */
  232. String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
  233. Delete(bsmartnamestr);
  234. Delete(smartnamestr);
  235. /* setup inheritance relationship between smart pointer templates */
  236. SwigType_inherit(smart, bsmart, 0, convcode);
  237. if (!GetFlag(bclass, "feature:smartptr"))
  238. Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
  239. Delete(convcode);
  240. Delete(bsmart);
  241. Delete(smart);
  242. } else {
  243. Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(smartptr), SwigType_namestr(clsname));
  244. }
  245. } else {
  246. if (GetFlag(bclass, "feature:smartptr"))
  247. Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name")));
  248. }
  249. if (!importmode) {
  250. String *btype = Copy(bname);
  251. SwigType_add_pointer(btype);
  252. SwigType_remember(btype);
  253. Delete(btype);
  254. }
  255. if (scopes) {
  256. SwigType_inherit_scope(scopes);
  257. }
  258. /* Set up inheritance in the symbol table */
  259. Symtab *st = Getattr(cls, "symtab");
  260. Symtab *bst = Getattr(bclass, "symtab");
  261. if (st == bst) {
  262. Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", SwigType_namestr(Getattr(cls, "name")));
  263. continue;
  264. }
  265. Symtab *s = Swig_symbol_current();
  266. Swig_symbol_setscope(st);
  267. Swig_symbol_inherit(bst);
  268. Swig_symbol_setscope(s);
  269. /* Recursively hit base classes */
  270. String *namestr = SwigType_namestr(Getattr(bclass, "name"));
  271. String *newcast = NewStringf("(%s *)%s", namestr, cast);
  272. Delete(namestr);
  273. cplus_inherit_types_impl(first, bclass, clsname, bases, baselist, ispublic, newcast);
  274. Delete(newcast);
  275. }
  276. }
  277. void append_list(List *lb, List *la) {
  278. if (la && lb) {
  279. for (Iterator bi = First(la); bi.item; bi = Next(bi)) {
  280. Append(lb, bi.item);
  281. }
  282. }
  283. }
  284. void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
  285. cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast);
  286. cplus_inherit_types_impl(first, cls, clsname, "protectedbases", "protectedbaselist", 0, cast);
  287. cplus_inherit_types_impl(first, cls, clsname, "privatebases", "privatebaselist", 0, cast);
  288. if (!cls)
  289. cls = first;
  290. List *allbases = NewList();
  291. append_list(allbases, Getattr(cls, "bases"));
  292. append_list(allbases, Getattr(cls, "protectedbases"));
  293. append_list(allbases, Getattr(cls, "privatebases"));
  294. if (Len(allbases)) {
  295. Setattr(cls, "allbases", allbases);
  296. }
  297. Delete(allbases);
  298. }
  299. /* ------------------------------------------------------------
  300. * top()
  301. * ------------------------------------------------------------ */
  302. virtual int top(Node *n) {
  303. importmode = 0;
  304. module = Getattr(n, "module");
  305. inclass = 0;
  306. normalize = 0;
  307. nsname = 0;
  308. nssymname = 0;
  309. classhash = Getattr(n, "classes");
  310. emit_children(n);
  311. normalize_list();
  312. SwigType_set_scope(0);
  313. return SWIG_OK;
  314. }
  315. /* ------------------------------------------------------------
  316. * moduleDirective()
  317. * ------------------------------------------------------------ */
  318. virtual int moduleDirective(Node *n) {
  319. if (!module) {
  320. module = n;
  321. }
  322. return SWIG_OK;
  323. }
  324. /* ------------------------------------------------------------
  325. * importDirective()
  326. * ------------------------------------------------------------ */
  327. virtual int importDirective(Node *n) {
  328. String *oldmodule = module;
  329. int oldimport = importmode;
  330. importmode = 1;
  331. module = 0;
  332. emit_children(n);
  333. importmode = oldimport;
  334. module = oldmodule;
  335. return SWIG_OK;
  336. }
  337. /* ------------------------------------------------------------
  338. * includeDirective()
  339. * externDirective()
  340. * extendDirective()
  341. * ------------------------------------------------------------ */
  342. virtual int includeDirective(Node *n) {
  343. return emit_children(n);
  344. }
  345. virtual int externDeclaration(Node *n) {
  346. return emit_children(n);
  347. }
  348. virtual int extendDirective(Node *n) {
  349. return emit_children(n);
  350. }
  351. /* ------------------------------------------------------------
  352. * classDeclaration()
  353. * ------------------------------------------------------------ */
  354. virtual int classDeclaration(Node *n) {
  355. String *name = Getattr(n, "name");
  356. String *tdname = Getattr(n, "tdname");
  357. String *unnamed = Getattr(n, "unnamed");
  358. String *storage = Getattr(n, "storage");
  359. String *kind = Getattr(n, "kind");
  360. Node *oldinclass = inclass;
  361. List *olist = normalize;
  362. Symtab *symtab;
  363. String *nname = 0;
  364. String *fname = 0;
  365. String *scopename = 0;
  366. String *template_default_expanded = 0;
  367. normalize = NewList();
  368. if (name) {
  369. if (SwigType_istemplate(name)) {
  370. // We need to fully resolve the name and expand default template parameters to make templates work correctly */
  371. Node *cn;
  372. SwigType *resolved_name = SwigType_typedef_resolve_all(name);
  373. SwigType *deftype_name = Swig_symbol_template_deftype(resolved_name, 0);
  374. fname = Copy(resolved_name);
  375. if (!Equal(resolved_name, deftype_name))
  376. template_default_expanded = Copy(deftype_name);
  377. if (!Equal(fname, name) && (cn = Swig_symbol_clookup_local(fname, 0))) {
  378. if ((n == cn)
  379. || (Strcmp(nodeType(cn), "template") == 0)
  380. || (Getattr(cn, "feature:onlychildren") != 0)
  381. || (Getattr(n, "feature:onlychildren") != 0)) {
  382. Swig_symbol_cadd(fname, n);
  383. if (template_default_expanded)
  384. Swig_symbol_cadd(template_default_expanded, n);
  385. SwigType_typedef_class(fname);
  386. scopename = Copy(fname);
  387. } else {
  388. Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
  389. Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
  390. scopename = 0;
  391. }
  392. } else {
  393. Swig_symbol_cadd(fname, n);
  394. SwigType_typedef_class(fname);
  395. scopename = Copy(fname);
  396. }
  397. Delete(deftype_name);
  398. Delete(resolved_name);
  399. } else {
  400. if ((CPlusPlus) || (unnamed)) {
  401. SwigType_typedef_class(name);
  402. } else {
  403. SwigType_typedef_class(NewStringf("%s %s", kind, name));
  404. }
  405. scopename = Copy(name);
  406. }
  407. } else {
  408. scopename = 0;
  409. }
  410. Setattr(n, "typepass:visit", "1");
  411. /* Need to set up a typedef if unnamed */
  412. if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
  413. SwigType_typedef(unnamed, tdname);
  414. }
  415. if (nsname && name) {
  416. nname = NewStringf("%s::%s", nsname, name);
  417. String *tdname = Getattr(n, "tdname");
  418. if (tdname) {
  419. tdname = NewStringf("%s::%s", nsname, tdname);
  420. Setattr(n, "tdname", tdname);
  421. }
  422. }
  423. if (nssymname) {
  424. if (GetFlag(n, "feature:nspace"))
  425. Setattr(n, "sym:nspace", nssymname);
  426. }
  427. SwigType_new_scope(scopename);
  428. SwigType_attach_symtab(Getattr(n, "symtab"));
  429. /* Inherit type definitions into the class */
  430. if (name) {
  431. cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
  432. }
  433. inclass = n;
  434. symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
  435. emit_children(n);
  436. Swig_symbol_setscope(symtab);
  437. Hash *ts = SwigType_pop_scope();
  438. Setattr(n, "typescope", ts);
  439. Delete(ts);
  440. Setattr(n, "module", module);
  441. // When a fully qualified templated type with default parameters is used in the parsed code,
  442. // the following additional symbols and scopes are needed for successful lookups
  443. if (template_default_expanded) {
  444. Swig_symbol_alias(template_default_expanded, Getattr(n, "symtab"));
  445. SwigType_scope_alias(template_default_expanded, Getattr(n, "typescope"));
  446. }
  447. /* Normalize deferred types */
  448. {
  449. normal_node *nn = new normal_node();
  450. nn->normallist = normalize;
  451. nn->symtab = Getattr(n, "symtab");
  452. nn->next = patch_list;
  453. nn->typescope = Getattr(n, "typescope");
  454. patch_list = nn;
  455. }
  456. normalize = olist;
  457. inclass = oldinclass;
  458. /* If in a namespace, patch the class name */
  459. if (nname) {
  460. Setattr(n, "name", nname);
  461. Delete(nname);
  462. }
  463. Delete(fname);
  464. return SWIG_OK;
  465. }
  466. /* ------------------------------------------------------------
  467. * namespaceDeclaration()
  468. * ------------------------------------------------------------ */
  469. virtual int templateDeclaration(Node *n) {
  470. String *name = Getattr(n, "name");
  471. String *ttype = Getattr(n, "templatetype");
  472. if (Strcmp(ttype, "class") == 0) {
  473. String *rname = SwigType_typedef_resolve_all(name);
  474. SwigType_typedef_class(rname);
  475. Delete(rname);
  476. } else if (Strcmp(ttype, "classforward") == 0) {
  477. String *rname = SwigType_typedef_resolve_all(name);
  478. SwigType_typedef_class(rname);
  479. Delete(rname);
  480. /* SwigType_typedef_class(name); */
  481. }
  482. return SWIG_OK;
  483. }
  484. /* ------------------------------------------------------------
  485. * classforwardDeclaration()
  486. * ------------------------------------------------------------ */
  487. virtual int classforwardDeclaration(Node *n) {
  488. /* Can't do inside a C struct because it breaks C nested structure wrapping */
  489. if ((!inclass) || (CPlusPlus)) {
  490. String *name = Getattr(n, "name");
  491. SwigType_typedef_class(name);
  492. }
  493. return SWIG_OK;
  494. }
  495. /* ------------------------------------------------------------
  496. * namespaceDeclaration()
  497. * ------------------------------------------------------------ */
  498. virtual int namespaceDeclaration(Node *n) {
  499. Symtab *symtab;
  500. String *name = Getattr(n, "name");
  501. String *alias = Getattr(n, "alias");
  502. List *olist = normalize;
  503. normalize = NewList();
  504. if (alias) {
  505. Typetab *ts = Getattr(n, "typescope");
  506. if (!ts) {
  507. Node *ns;
  508. /* Create a empty scope for the alias */
  509. ns = Getattr(n, "namespace");
  510. if (ns) {
  511. SwigType_scope_alias(name, Getattr(ns, "typescope"));
  512. }
  513. ts = Getattr(ns, "typescope");
  514. Setattr(n, "typescope", ts);
  515. }
  516. /* Namespace alias */
  517. return SWIG_OK;
  518. } else {
  519. if (name) {
  520. Node *nn = Swig_symbol_clookup(name, n);
  521. Hash *ts = 0;
  522. if (nn)
  523. ts = Getattr(nn, "typescope");
  524. if (!ts) {
  525. SwigType_new_scope(name);
  526. SwigType_attach_symtab(Getattr(n, "symtab"));
  527. } else {
  528. SwigType_set_scope(ts);
  529. }
  530. }
  531. String *oldnsname = nsname;
  532. String *oldnssymname = nssymname;
  533. nsname = Swig_symbol_qualified(Getattr(n, "symtab"));
  534. nssymname = Swig_symbol_qualified_language_scopename(Getattr(n, "symtab"));
  535. symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
  536. emit_children(n);
  537. Swig_symbol_setscope(symtab);
  538. if (name) {
  539. Hash *ts = SwigType_pop_scope();
  540. Setattr(n, "typescope", ts);
  541. Delete(ts);
  542. }
  543. /* Normalize deferred types */
  544. {
  545. normal_node *nn = new normal_node();
  546. nn->normallist = normalize;
  547. nn->symtab = Getattr(n, "symtab");
  548. nn->next = patch_list;
  549. nn->typescope = Getattr(n, "typescope");
  550. patch_list = nn;
  551. }
  552. normalize = olist;
  553. Delete(nssymname);
  554. nssymname = oldnssymname;
  555. Delete(nsname);
  556. nsname = oldnsname;
  557. return SWIG_OK;
  558. }
  559. }
  560. /* ------------------------------------------------------------
  561. * cDeclaration()
  562. * ------------------------------------------------------------ */
  563. virtual int cDeclaration(Node *n) {
  564. if (NoExcept) {
  565. Delattr(n, "throws");
  566. }
  567. /* Normalize types. */
  568. SwigType *ty = Getattr(n, "type");
  569. normalize_type(ty);
  570. SwigType *decl = Getattr(n, "decl");
  571. if (decl) {
  572. normalize_type(decl);
  573. }
  574. normalize_parms(Getattr(n, "parms"));
  575. normalize_parms(Getattr(n, "throws"));
  576. if (GetFlag(n, "conversion_operator")) {
  577. /* The call to the operator in the generated wrapper must be fully qualified in order to compile */
  578. SwigType *name = Getattr(n, "name");
  579. SwigType *qualifiedname = Swig_symbol_string_qualify(name,0);
  580. Clear(name);
  581. Append(name, qualifiedname);
  582. Delete(qualifiedname);
  583. }
  584. if (checkAttribute(n, "storage", "typedef")) {
  585. String *name = Getattr(n, "name");
  586. ty = Getattr(n, "type");
  587. decl = Getattr(n, "decl");
  588. SwigType *t = Copy(ty);
  589. {
  590. /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */
  591. if (Swig_scopename_check(t) && strncmp(Char(t), "::", 2)) {
  592. String *base, *prefix, *qprefix;
  593. base = Swig_scopename_last(t);
  594. prefix = Swig_scopename_prefix(t);
  595. qprefix = SwigType_typedef_qualified(prefix);
  596. Delete(t);
  597. t = NewStringf("%s::%s", qprefix, base);
  598. Delete(base);
  599. Delete(prefix);
  600. Delete(qprefix);
  601. }
  602. }
  603. SwigType_push(t, decl);
  604. if (CPlusPlus) {
  605. Replaceall(t, "struct ", "");
  606. Replaceall(t, "union ", "");
  607. Replaceall(t, "class ", "");
  608. }
  609. SwigType_typedef(t, name);
  610. }
  611. /* If namespaces are active. We need to patch the name with a namespace prefix */
  612. if (nsname && !inclass) {
  613. String *name = Getattr(n, "name");
  614. if (name) {
  615. String *nname = NewStringf("%s::%s", nsname, name);
  616. Setattr(n, "name", nname);
  617. Delete(nname);
  618. }
  619. }
  620. clean_overloaded(n);
  621. return SWIG_OK;
  622. }
  623. /* ------------------------------------------------------------
  624. * constructorDeclaration()
  625. * ------------------------------------------------------------ */
  626. virtual int constructorDeclaration(Node *n) {
  627. if (NoExcept) {
  628. Delattr(n, "throws");
  629. }
  630. normalize_parms(Getattr(n, "parms"));
  631. normalize_parms(Getattr(n, "throws"));
  632. /* If in a namespace, patch the class name */
  633. if (nsname) {
  634. String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
  635. Setattr(n, "name", nname);
  636. }
  637. clean_overloaded(n);
  638. return SWIG_OK;
  639. }
  640. /* ------------------------------------------------------------
  641. * destructorDeclaration()
  642. * ------------------------------------------------------------ */
  643. virtual int destructorDeclaration(Node *n) {
  644. /* If in a namespace, patch the class name */
  645. if (nsname) {
  646. String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
  647. Setattr(n, "name", nname);
  648. }
  649. return SWIG_OK;
  650. }
  651. /* ------------------------------------------------------------
  652. * constantDirective()
  653. * ------------------------------------------------------------ */
  654. virtual int constantDirective(Node *n) {
  655. SwigType *ty = Getattr(n, "type");
  656. if (ty) {
  657. Setattr(n, "type", SwigType_typedef_qualified(ty));
  658. }
  659. return SWIG_OK;
  660. }
  661. /* ------------------------------------------------------------
  662. * enumDeclaration()
  663. * ------------------------------------------------------------ */
  664. virtual int enumDeclaration(Node *n) {
  665. String *name = Getattr(n, "name");
  666. if (name) {
  667. String *scope = 0;
  668. // Add a typedef to the type table so that we can use 'enum Name' as well as just 'Name'
  669. if (nsname || inclass) {
  670. // But first correct the name and tdname to contain the fully qualified scopename
  671. if (nsname && inclass) {
  672. scope = NewStringf("%s::%s", nsname, Getattr(inclass, "name"));
  673. } else if (nsname) {
  674. scope = NewStringf("%s", nsname);
  675. } else if (inclass) {
  676. scope = NewStringf("%s", Getattr(inclass, "name"));
  677. }
  678. String *nname = NewStringf("%s::%s", scope, name);
  679. Setattr(n, "name", nname);
  680. String *tdname = Getattr(n, "tdname");
  681. if (tdname) {
  682. tdname = NewStringf("%s::%s", scope, tdname);
  683. Setattr(n, "tdname", tdname);
  684. }
  685. SwigType *t = NewStringf("enum %s", nname);
  686. SwigType_typedef(t, name);
  687. } else {
  688. SwigType *t = NewStringf("enum %s", name);
  689. SwigType_typedef(t, name);
  690. }
  691. Delete(scope);
  692. }
  693. String *tdname = Getattr(n, "tdname");
  694. String *unnamed = Getattr(n, "unnamed");
  695. String *storage = Getattr(n, "storage");
  696. // Construct enumtype - for declaring an enum of this type with SwigType_ltype() etc
  697. String *enumtype = 0;
  698. if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
  699. enumtype = Copy(Getattr(n, "tdname"));
  700. } else if (name) {
  701. enumtype = NewStringf("%s%s", CPlusPlus ? "" : "enum ", Getattr(n, "name"));
  702. } else {
  703. // anonymous enums
  704. enumtype = Copy(Getattr(n, "type"));
  705. }
  706. Setattr(n, "enumtype", enumtype);
  707. if (nssymname) {
  708. if (GetFlag(n, "feature:nspace"))
  709. Setattr(n, "sym:nspace", nssymname);
  710. }
  711. // This block of code is for dealing with %ignore on an enum item where the target language
  712. // attempts to use the C enum value in the target language itself and expects the previous enum value
  713. // to be one more than the previous value... the previous enum item might not exist if it is ignored!
  714. // - It sets the first non-ignored enum item with the "firstenumitem" attribute.
  715. // - It adds an enumvalue attribute if the previous enum item is ignored
  716. {
  717. Node *c;
  718. int count = 0;
  719. String *previous = 0;
  720. bool previous_ignored = false;
  721. bool firstenumitem = false;
  722. for (c = firstChild(n); c; c = nextSibling(c)) {
  723. assert(strcmp(Char(nodeType(c)), "enumitem") == 0);
  724. bool reset;
  725. String *enumvalue = Getattr(c, "enumvalue");
  726. if (GetFlag(c, "feature:ignore") || !Getattr(c, "sym:name")) {
  727. reset = enumvalue ? true : false;
  728. previous_ignored = true;
  729. } else {
  730. if (!enumvalue && previous_ignored) {
  731. if (previous)
  732. Setattr(c, "enumvalue", NewStringf("(%s) + %d", previous, count+1));
  733. else
  734. Setattr(c, "enumvalue", NewStringf("%d", count));
  735. SetFlag(c, "virtenumvalue"); // identify enumvalue as virtual, ie not from the parsed source
  736. }
  737. if (!firstenumitem) {
  738. SetFlag(c, "firstenumitem");
  739. firstenumitem = true;
  740. }
  741. reset = true;
  742. previous_ignored = false;
  743. }
  744. if (reset) {
  745. previous = enumvalue ? enumvalue : Getattr(c, "name");
  746. count = 0;
  747. } else {
  748. count++;
  749. }
  750. }
  751. }
  752. emit_children(n);
  753. return SWIG_OK;
  754. }
  755. /* ------------------------------------------------------------
  756. * enumvalueDeclaration()
  757. * ------------------------------------------------------------ */
  758. virtual int enumvalueDeclaration(Node *n) {
  759. String *name = Getattr(n, "name");
  760. String *value = Getattr(n, "value");
  761. if (!value)
  762. value = name;
  763. if (Strcmp(value, name) == 0) {
  764. String *new_value;
  765. if ((nsname || inclass) && cparse_cplusplus) {
  766. new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
  767. } else {
  768. new_value = NewString(value);
  769. }
  770. if ((nsname || inclass) && !cparse_cplusplus) {
  771. String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
  772. Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */
  773. }
  774. Setattr(n, "value", new_value);
  775. Delete(new_value);
  776. }
  777. Node *next = nextSibling(n);
  778. // Make up an enumvalue if one was not specified in the parsed code (not designed to be used on enum items and %ignore - enumvalue will be set instead)
  779. if (!GetFlag(n, "feature:ignore")) {
  780. if (Getattr(n, "_last") && !Getattr(n, "enumvalue")) { // Only the first enum item has _last set (Note: first non-ignored enum item has firstenumitem set)
  781. Setattr(n, "enumvalueex", "0");
  782. }
  783. if (next && !Getattr(next, "enumvalue")) {
  784. Setattr(next, "enumvalueex", NewStringf("%s + 1", Getattr(n, "sym:name")));
  785. }
  786. }
  787. return SWIG_OK;
  788. }
  789. /* ------------------------------------------------------------
  790. * enumforwardDeclaration()
  791. * ------------------------------------------------------------ */
  792. virtual int enumforwardDeclaration(Node *n) {
  793. // Use enumDeclaration() to do all the hard work.
  794. // Note that no children can be emitted in a forward declaration as there aren't any.
  795. return enumDeclaration(n);
  796. }
  797. #ifdef DEBUG_OVERLOADED
  798. static void show_overloaded(Node *n) {
  799. Node *c = Getattr(n, "sym:overloaded");
  800. Node *checkoverloaded = c;
  801. Printf(stdout, "-------------------- overloaded start %s sym:overloaded():%p -------------------------------\n", Getattr(n, "name"), c);
  802. while (c) {
  803. if (Getattr(c, "error")) {
  804. c = Getattr(c, "sym:nextSibling");
  805. continue;
  806. }
  807. if (Getattr(c, "sym:overloaded") != checkoverloaded) {
  808. Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
  809. Swig_print_node(c);
  810. exit (1);
  811. }
  812. String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
  813. Printf(stdout, " show_overloaded %s::%s(%s) [%s] nodeType:%s\n", parentNode(c) ? Getattr(parentNode(c), "name") : "NOPARENT", Getattr(c, "name"), decl, Getattr(c, "sym:overname"), nodeType(c));
  814. if (!Getattr(c, "sym:overloaded")) {
  815. Printf(stdout, "sym:overloaded error.....%p\n", c);
  816. Swig_print_node(c);
  817. exit (1);
  818. }
  819. c = Getattr(c, "sym:nextSibling");
  820. }
  821. Printf(stdout, "-------------------- overloaded end %s -------------------------------\n", Getattr(n, "name"));
  822. }
  823. #endif
  824. /* ------------------------------------------------------------
  825. * usingDeclaration()
  826. * ------------------------------------------------------------ */
  827. virtual int usingDeclaration(Node *n) {
  828. if (Getattr(n, "namespace")) {
  829. /* using namespace id */
  830. /* For a namespace import. We set up inheritance in the type system */
  831. Node *ns = Getattr(n, "node");
  832. if (ns) {
  833. Typetab *ts = Getattr(ns, "typescope");
  834. if (ts) {
  835. SwigType_using_scope(ts);
  836. }
  837. }
  838. return SWIG_OK;
  839. } else {
  840. Node *ns;
  841. /* using id */
  842. Symtab *stab = Getattr(n, "sym:symtab");
  843. if (stab) {
  844. String *uname = Getattr(n, "uname");
  845. ns = Swig_symbol_clookup(uname, stab);
  846. if (!ns && SwigType_istemplate(uname)) {
  847. String *tmp = Swig_symbol_template_deftype(uname, 0);
  848. if (!Equal(tmp, uname)) {
  849. ns = Swig_symbol_clookup(tmp, stab);
  850. }
  851. Delete(tmp);
  852. }
  853. } else {
  854. ns = 0;
  855. }
  856. if (!ns) {
  857. if (is_public(n)) {
  858. Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname")));
  859. }
  860. } else {
  861. /* Only a single symbol is being used. There are only a few symbols that
  862. we actually care about. These are typedef, class declarations, and enum */
  863. String *ntype = nodeType(ns);
  864. if (Strcmp(ntype, "cdecl") == 0) {
  865. if (checkAttribute(ns, "storage", "typedef")) {
  866. /* A typedef declaration */
  867. String *uname = Getattr(n, "uname");
  868. SwigType_typedef_using(uname);
  869. } else {
  870. /* A normal C declaration. */
  871. if ((inclass) && (!GetFlag(n, "feature:ignore")) && (Getattr(n, "sym:name"))) {
  872. Node *c = ns;
  873. Node *unodes = 0, *last_unodes = 0;
  874. int ccount = 0;
  875. String *symname = Getattr(n, "sym:name");
  876. while (c) {
  877. if (Strcmp(nodeType(c), "cdecl") == 0) {
  878. if (!(checkAttribute(c, "storage", "static")
  879. || checkAttribute(c, "storage", "typedef")
  880. || checkAttribute(c, "storage", "friend")
  881. || (Getattr(c, "feature:extend") && !Getattr(c, "code"))
  882. || GetFlag(c, "feature:ignore"))) {
  883. /* Don't generate a method if the method is overridden in this class,
  884. * for example don't generate another m(bool) should there be a Base::m(bool) :
  885. * struct Derived : Base {
  886. * void m(bool);
  887. * using Base::m;
  888. * };
  889. */
  890. String *csymname = Getattr(c, "sym:name");
  891. if (!csymname || (Strcmp(csymname, symname) == 0)) {
  892. {
  893. String *decl = Getattr(c, "decl");
  894. Node *over = Getattr(n, "sym:overloaded");
  895. int match = 0;
  896. while (over) {
  897. String *odecl = Getattr(over, "decl");
  898. if (Cmp(decl, odecl) == 0) {
  899. match = 1;
  900. break;
  901. }
  902. over = Getattr(over, "sym:nextSibling");
  903. }
  904. if (match) {
  905. c = Getattr(c, "csym:nextSibling");
  906. continue;
  907. }
  908. }
  909. Node *nn = copyNode(c);
  910. Delattr(nn, "access"); // access might be different from the method in the base class
  911. Setattr(nn, "access", Getattr(n, "access"));
  912. if (!Getattr(nn, "sym:name"))
  913. Setattr(nn, "sym:name", symname);
  914. if (!GetFlag(nn, "feature:ignore")) {
  915. ParmList *parms = CopyParmList(Getattr(c, "parms"));
  916. int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
  917. int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
  918. Setattr(nn, "parms", parms);
  919. Delete(parms);
  920. if (Getattr(n, "feature:extend")) {
  921. String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
  922. for (ParmList *p = parms; p;) {
  923. Append(ucode, Getattr(p, "name"));
  924. p = nextSibling(p);
  925. if (p)
  926. Append(ucode, ",");
  927. }
  928. Append(ucode, "); }");
  929. Setattr(nn, "code", ucode);
  930. Delete(ucode);
  931. }
  932. ParmList *throw_parm_list = Getattr(c, "throws");
  933. if (throw_parm_list)
  934. Setattr(nn, "throws", CopyParmList(throw_parm_list));
  935. ccount++;
  936. if (!last_unodes) {
  937. last_unodes = nn;
  938. unodes = nn;
  939. } else {
  940. Setattr(nn, "previousSibling", last_unodes);
  941. Setattr(last_unodes, "nextSibling", nn);
  942. Setattr(nn, "sym:previousSibling", last_unodes);
  943. Setattr(last_unodes, "sym:nextSibling", nn);
  944. Setattr(nn, "sym:overloaded", unodes);
  945. Setattr(unodes, "sym:overloaded", unodes);
  946. last_unodes = nn;
  947. }
  948. } else {
  949. Delete(nn);
  950. }
  951. }
  952. }
  953. }
  954. c = Getattr(c, "csym:nextSibling");
  955. }
  956. if (unodes) {
  957. set_firstChild(n, unodes);
  958. if (ccount > 1) {
  959. if (!Getattr(n, "sym:overloaded")) {
  960. Setattr(n, "sym:overloaded", n);
  961. Setattr(n, "sym:overname", "_SWIG_0");
  962. }
  963. }
  964. }
  965. /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
  966. * list of overloaded methods we have just added in as child nodes to the "using" node.
  967. * The node will still exist, it is just the symbol table linked list of overloaded methods
  968. * which is hacked. */
  969. if (Getattr(n, "sym:overloaded"))
  970. {
  971. int cnt = 0;
  972. #ifdef DEBUG_OVERLOADED
  973. Node *debugnode = n;
  974. show_overloaded(n);
  975. #endif
  976. if (!firstChild(n)) {
  977. // Remove from overloaded list ('using' node does not actually end up adding in any methods)
  978. Node *ps = Getattr(n, "sym:previousSibling");
  979. Node *ns = Getattr(n, "sym:nextSibling");
  980. if (ps) {
  981. Setattr(ps, "sym:nextSibling", ns);
  982. }
  983. if (ns) {
  984. Setattr(ns, "sym:previousSibling", ps);
  985. }
  986. } else {
  987. // The 'using' node results in methods being added in - slot in the these methods here
  988. Node *ps = Getattr(n, "sym:previousSibling");
  989. Node *ns = Getattr(n, "sym:nextSibling");
  990. Node *fc = firstChild(n);
  991. Node *pp = fc;
  992. Node *firstoverloaded = Getattr(n, "sym:overloaded");
  993. if (firstoverloaded == n) {
  994. // This 'using' node we are cutting out was the first node in the overloaded list.
  995. // Change the first node in the list to its first sibling
  996. Delattr(firstoverloaded, "sym:overloaded");
  997. Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
  998. firstoverloaded = fc;
  999. while (nnn) {
  1000. Setattr(nnn, "sym:overloaded", firstoverloaded);
  1001. nnn = Getattr(nnn, "sym:nextSibling");
  1002. }
  1003. }
  1004. while (pp) {
  1005. Node *ppn = Getattr(pp, "sym:nextSibling");
  1006. Setattr(pp, "sym:overloaded", firstoverloaded);
  1007. Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
  1008. if (ppn)
  1009. pp = ppn;
  1010. else
  1011. break;
  1012. }
  1013. if (ps) {
  1014. Setattr(ps, "sym:nextSibling", fc);
  1015. Setattr(fc, "sym:previousSibling", ps);
  1016. }
  1017. if (ns) {
  1018. Setattr(ns, "sym:previousSibling", pp);
  1019. Setattr(pp, "sym:nextSibling", ns);
  1020. }
  1021. #ifdef DEBUG_OVERLOADED
  1022. debugnode = firstoverloaded;
  1023. #endif
  1024. }
  1025. Delattr(n, "sym:previousSibling");
  1026. Delattr(n, "sym:nextSibling");
  1027. Delattr(n, "sym:overloaded");
  1028. Delattr(n, "sym:overname");
  1029. #ifdef DEBUG_OVERLOADED
  1030. show_overloaded(debugnode);
  1031. #endif
  1032. clean_overloaded(n); // Needed?
  1033. }
  1034. }
  1035. }
  1036. } else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
  1037. /* We install the using class name as kind of a typedef back to the original class */
  1038. String *uname = Getattr(n, "uname");
  1039. /* Import into current type scope */
  1040. SwigType_typedef_using(uname);
  1041. } else if (Strcmp(ntype, "enum") == 0) {
  1042. SwigType_typedef_using(Getattr(n, "uname"));
  1043. }
  1044. }
  1045. }
  1046. return SWIG_OK;
  1047. }
  1048. /* ------------------------------------------------------------
  1049. * typemapDirective()
  1050. * ------------------------------------------------------------ */
  1051. virtual int typemapDirective(Node *n) {
  1052. if (inclass || nsname) {
  1053. Node *items = firstChild(n);
  1054. while (items) {
  1055. Parm *pattern = Getattr(items, "pattern");
  1056. Parm *parms = Getattr(items, "parms");
  1057. normalize_later(pattern);
  1058. normalize_later(parms);
  1059. items = nextSibling(items);
  1060. }
  1061. }
  1062. return SWIG_OK;
  1063. }
  1064. /* ------------------------------------------------------------
  1065. * typemapcopyDirective()
  1066. * ------------------------------------------------------------ */
  1067. virtual int typemapcopyDirective(Node *n) {
  1068. if (inclass || nsname) {
  1069. Node *items = firstChild(n);
  1070. ParmList *pattern = Getattr(n, "pattern");
  1071. normalize_later(pattern);
  1072. while (items) {
  1073. ParmList *npattern = Getattr(items, "pattern");
  1074. normalize_later(npattern);
  1075. items = nextSibling(items);
  1076. }
  1077. }
  1078. return SWIG_OK;
  1079. }
  1080. /* ------------------------------------------------------------
  1081. * applyDirective()
  1082. * ------------------------------------------------------------ */
  1083. virtual int applyDirective(Node *n) {
  1084. if (inclass || nsname) {
  1085. ParmList *pattern = Getattr(n, "pattern");
  1086. normalize_later(pattern);
  1087. Node *items = firstChild(n);
  1088. while (items) {
  1089. Parm *apattern = Getattr(items, "pattern");
  1090. normalize_later(apattern);
  1091. items = nextSibling(items);
  1092. }
  1093. }
  1094. return SWIG_OK;
  1095. }
  1096. /* ------------------------------------------------------------
  1097. * clearDirective()
  1098. * ------------------------------------------------------------ */
  1099. virtual int clearDirective(Node *n) {
  1100. if (inclass || nsname) {
  1101. Node *p;
  1102. for (p = firstChild(n); p; p = nextSibling(p)) {
  1103. ParmList *pattern = Getattr(p, "pattern");
  1104. normalize_later(pattern);
  1105. }
  1106. }
  1107. return SWIG_OK;
  1108. }
  1109. public:
  1110. static void pass(Node *n) {
  1111. TypePass t;
  1112. t.top(n);
  1113. }
  1114. };
  1115. void Swig_process_types(Node *n) {
  1116. if (!n)
  1117. return;
  1118. TypePass::pass(n);
  1119. }