PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1-3-26/SWIG/Source/Modules/lang.cxx

#
C++ | 2140 lines | 1507 code | 276 blank | 357 comment | 421 complexity | 7f2b03601dec99995795574e464b96aa MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * lang.cxx
  3. *
  4. * Language base class functions. Default C++ handling is also implemented here.
  5. *
  6. * Author(s) : David Beazley (beazley@cs.uchicago.edu)
  7. *
  8. * Copyright (C) 1998-2000. The University of Chicago
  9. * Copyright (C) 1995-1998. The University of Utah and The Regents of the
  10. * University of California.
  11. *
  12. * See the file LICENSE for information on usage and redistribution.
  13. * ----------------------------------------------------------------------------- */
  14. char cvsroot_lang_cxx[] = "$Header$";
  15. #include "swigmod.h"
  16. #include "cparse.h"
  17. #include <ctype.h>
  18. static int director_mode = 0; /* set to 0 on default */
  19. static int director_protected_mode = 0; /* set to 0 on default */
  20. /* Set director_protected_mode */
  21. void Wrapper_director_mode_set(int flag) {
  22. director_mode = flag;
  23. }
  24. void Wrapper_director_protected_mode_set(int flag) {
  25. director_protected_mode = flag;
  26. }
  27. extern "C" {
  28. int Swig_director_mode()
  29. {
  30. return director_mode;
  31. }
  32. int Swig_need_protected()
  33. {
  34. return director_protected_mode;
  35. }
  36. }
  37. /* Some status variables used during parsing */
  38. static int InClass = 0; /* Parsing C++ or not */
  39. static String *ClassName = 0; /* This is the real name of the current class */
  40. static String *ClassPrefix = 0; /* Class prefix */
  41. static String *ClassType = 0; /* Fully qualified type name to use */
  42. int Abstract = 0;
  43. int ImportMode = 0;
  44. int IsVirtual = 0;
  45. static String *AttributeFunctionGet = 0;
  46. static String *AttributeFunctionSet = 0;
  47. static Node *CurrentClass = 0;
  48. int line_number = 0;
  49. char *input_file = 0;
  50. int SmartPointer = 0;
  51. extern int GenerateDefault;
  52. extern int ForceExtern;
  53. extern int AddExtern;
  54. /* import modes */
  55. #define IMPORT_MODE 1
  56. #define IMPORT_MODULE 2
  57. /* ----------------------------------------------------------------------
  58. * Dispatcher::emit_one()
  59. *
  60. * Dispatch a single node
  61. * ---------------------------------------------------------------------- */
  62. int Dispatcher::emit_one(Node *n) {
  63. String *wrn;
  64. int ret = SWIG_OK;
  65. char *tag = Char(nodeType(n));
  66. if (!tag) {
  67. /* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree
  68. node!\n"); */
  69. return SWIG_OK;
  70. }
  71. /* Do not proceed if marked with an error */
  72. if (Getattr(n,"error")) return SWIG_OK;
  73. /* Look for warnings */
  74. wrn = Getattr(n,"feature:warnfilter");
  75. if (wrn) {
  76. Swig_warnfilter(wrn,1);
  77. }
  78. /* ============================================================
  79. * C/C++ parsing
  80. * ============================================================ */
  81. if (strcmp(tag,"extern") == 0) {
  82. ret = externDeclaration(n);
  83. } else if (strcmp(tag,"cdecl") == 0) {
  84. ret = cDeclaration(n);
  85. } else if (strcmp(tag,"enum") == 0) {
  86. ret = enumDeclaration(n);
  87. } else if (strcmp(tag,"enumitem") == 0) {
  88. ret = enumvalueDeclaration(n);
  89. } else if (strcmp(tag,"enumforward") == 0) {
  90. ret = enumforwardDeclaration(n);
  91. } else if (strcmp(tag,"class") == 0) {
  92. ret = classDeclaration(n);
  93. } else if (strcmp(tag,"classforward") == 0) {
  94. ret = classforwardDeclaration(n);
  95. } else if (strcmp(tag,"constructor") == 0) {
  96. ret = constructorDeclaration(n);
  97. } else if (strcmp(tag,"destructor") == 0) {
  98. ret = destructorDeclaration(n);
  99. } else if (strcmp(tag,"access") == 0) {
  100. ret = accessDeclaration(n);
  101. } else if (strcmp(tag,"using") == 0) {
  102. ret = usingDeclaration(n);
  103. } else if (strcmp(tag,"namespace") == 0) {
  104. ret = namespaceDeclaration(n);
  105. } else if (strcmp(tag,"template") == 0) {
  106. ret = templateDeclaration(n);
  107. }
  108. /* ===============================================================
  109. * SWIG directives
  110. * =============================================================== */
  111. else if (strcmp(tag,"top") == 0) {
  112. ret = top(n);
  113. } else if (strcmp(tag,"extend") == 0) {
  114. ret = extendDirective(n);
  115. } else if (strcmp(tag,"apply") == 0) {
  116. ret = applyDirective(n);
  117. } else if (strcmp(tag,"clear") == 0) {
  118. ret = clearDirective(n);
  119. } else if (strcmp(tag,"constant") == 0) {
  120. ret = constantDirective(n);
  121. } else if (strcmp(tag,"fragment") == 0) {
  122. ret = fragmentDirective(n);
  123. } else if (strcmp(tag,"import") == 0) {
  124. ret = importDirective(n);
  125. } else if (strcmp(tag,"include") == 0) {
  126. ret = includeDirective(n);
  127. } else if (strcmp(tag,"insert") == 0) {
  128. ret = insertDirective(n);
  129. } else if (strcmp(tag,"module") == 0) {
  130. ret = moduleDirective(n);
  131. } else if (strcmp(tag,"native") == 0) {
  132. ret = nativeDirective(n);
  133. } else if (strcmp(tag,"pragma") == 0) {
  134. ret = pragmaDirective(n);
  135. } else if (strcmp(tag,"typemap") == 0) {
  136. ret = typemapDirective(n);
  137. } else if (strcmp(tag,"typemapcopy") == 0) {
  138. ret = typemapcopyDirective(n);
  139. } else if (strcmp(tag,"typemapitem") == 0) {
  140. ret = typemapitemDirective(n);
  141. } else if (strcmp(tag,"types") == 0) {
  142. ret = typesDirective(n);
  143. } else {
  144. Printf(stderr,"%s:%d. Unrecognized parse tree node type '%s'\n", input_file, line_number, tag);
  145. ret = SWIG_ERROR;
  146. }
  147. if (wrn) {
  148. Swig_warnfilter(wrn,0);
  149. }
  150. return ret;
  151. }
  152. /* ----------------------------------------------------------------------
  153. * Dispatcher::emit_children()
  154. *
  155. * Emit all children.
  156. * ---------------------------------------------------------------------- */
  157. int Dispatcher::emit_children(Node *n) {
  158. Node *c;
  159. char *eo = Char(Getattr(n,"feature:emitonlychildren"));
  160. for (c = firstChild(n); c; c = nextSibling(c)) {
  161. if (eo) {
  162. const char *tag = Char(nodeType(c));
  163. if (Strcmp(tag,"cdecl") == 0) {
  164. if (checkAttribute(c, "storage", "typedef"))
  165. tag = "typedef";
  166. }
  167. if (strstr(eo,tag) == 0) {
  168. continue;
  169. }
  170. }
  171. emit_one(c);
  172. }
  173. return SWIG_OK;
  174. }
  175. /* Stubs for dispatcher class. We don't do anything by default---up to derived class
  176. to fill in traversal code */
  177. int Dispatcher::defaultHandler(Node *) { return SWIG_OK; }
  178. int Dispatcher::extendDirective(Node *n) { return defaultHandler(n); }
  179. int Dispatcher::applyDirective(Node *n) { return defaultHandler(n); }
  180. int Dispatcher::clearDirective(Node *n) { return defaultHandler(n); }
  181. int Dispatcher::constantDirective(Node *n) { return defaultHandler(n); }
  182. int Dispatcher::fragmentDirective(Node *n) { return defaultHandler(n); }
  183. int Dispatcher::importDirective(Node *n) { return defaultHandler(n); }
  184. int Dispatcher::includeDirective(Node *n) { return defaultHandler(n); }
  185. int Dispatcher::insertDirective(Node *n) { return defaultHandler(n); }
  186. int Dispatcher::moduleDirective(Node *n) { return defaultHandler(n); }
  187. int Dispatcher::nativeDirective(Node *n) { return defaultHandler(n); }
  188. int Dispatcher::pragmaDirective(Node *n) { return defaultHandler(n); }
  189. int Dispatcher::typemapDirective(Node *n) { return defaultHandler(n); }
  190. int Dispatcher::typemapitemDirective(Node *n) { return defaultHandler(n); }
  191. int Dispatcher::typemapcopyDirective(Node *n) { return defaultHandler(n); }
  192. int Dispatcher::typesDirective(Node *n) { return defaultHandler(n); }
  193. int Dispatcher::cDeclaration(Node *n) { return defaultHandler(n); }
  194. int Dispatcher::externDeclaration(Node *n) { return defaultHandler(n); }
  195. int Dispatcher::enumDeclaration(Node *n) { return defaultHandler(n); }
  196. int Dispatcher::enumvalueDeclaration(Node *n) { return defaultHandler(n); }
  197. int Dispatcher::enumforwardDeclaration(Node *n) { return defaultHandler(n); }
  198. int Dispatcher::classDeclaration(Node *n) { return defaultHandler(n); }
  199. int Dispatcher::templateDeclaration(Node *n) { return defaultHandler(n); }
  200. int Dispatcher::classforwardDeclaration(Node *n) { return defaultHandler(n); }
  201. int Dispatcher::constructorDeclaration(Node *n) { return defaultHandler(n); }
  202. int Dispatcher::destructorDeclaration(Node *n) { return defaultHandler(n); }
  203. int Dispatcher::accessDeclaration(Node *n) { return defaultHandler(n); }
  204. int Dispatcher::usingDeclaration(Node *n) { return defaultHandler(n); }
  205. int Dispatcher::namespaceDeclaration(Node *n) { return defaultHandler(n); }
  206. /* Allocators */
  207. Language::Language() :
  208. none_comparison(NewString("$arg != 0")),
  209. director_ctor_code(NewString("")),
  210. director_prot_ctor_code(0),
  211. symbols(NewHash()),
  212. classtypes(NewHash()),
  213. enumtypes(NewHash()),
  214. overloading(0),
  215. multiinput(0),
  216. directors(0)
  217. {
  218. argc_template_string = NewString("argc");
  219. argv_template_string = NewString("argv[%d]");
  220. /* Default director constructor code, passed to Swig_ConstructorToFunction */
  221. Printv(director_ctor_code,
  222. "if ( $comparison ) { /* subclassed */\n",
  223. " $director_new \n",
  224. "} else {\n",
  225. " $nondirector_new \n",
  226. "}\n", NIL);
  227. /*
  228. Default director 'protected' constructor code, disable by
  229. default. Each language that need it, has to define it.
  230. */
  231. director_prot_ctor_code = 0;
  232. director_multiple_inheritance = 1;
  233. director_language = 0;
  234. }
  235. Language::~Language() {
  236. Delete(symbols);
  237. Delete(classtypes);
  238. Delete(enumtypes);
  239. }
  240. /* ----------------------------------------------------------------------
  241. emit_one()
  242. ---------------------------------------------------------------------- */
  243. int Language::emit_one(Node *n) {
  244. int ret;
  245. int oldext;
  246. if (!n) return SWIG_OK;
  247. if (GetFlag(n,"feature:ignore")
  248. && !Getattr(n,"feature:onlychildren")) return SWIG_OK;
  249. oldext = Extend;
  250. if (Getattr(n,"feature:extend")) Extend = 1;
  251. line_number = Getline(n);
  252. input_file = Char(Getfile(n));
  253. /*
  254. symtab = Getattr(n,"symtab");
  255. if (symtab) {
  256. symtab = Swig_symbol_setscope(symtab);
  257. }
  258. */
  259. ret = Dispatcher::emit_one(n);
  260. /*
  261. if (symtab) {
  262. Swig_symbol_setscope(symtab);
  263. }
  264. */
  265. Extend = oldext;
  266. return ret;
  267. }
  268. static Parm *nonvoid_parms(Parm *p) {
  269. if (p) {
  270. SwigType *t = Getattr(p,"type");
  271. if (SwigType_type(t) == T_VOID) return 0;
  272. }
  273. return p;
  274. }
  275. /* -----------------------------------------------------------------------------
  276. * cplus_value_type()
  277. *
  278. * Returns the alternative value type needed in C++ for class value
  279. * types. When swig is not sure about using a plain $ltype value,
  280. * since the class doesn't have a default constructor, or it can't be
  281. * assigned, you will get back 'SwigValueWrapper<type >'.
  282. *
  283. * ----------------------------------------------------------------------------- */
  284. SwigType *cplus_value_type(SwigType *t) {
  285. return SwigType_alttype(t, 0);
  286. }
  287. static Node *first_nontemplate(Node *n) {
  288. while (n) {
  289. if (Strcmp(nodeType(n),"template") != 0) return n;
  290. n = Getattr(n,"sym:nextSibling");
  291. }
  292. return n;
  293. }
  294. /* --------------------------------------------------------------------------
  295. * swig_pragma()
  296. *
  297. * Handle swig pragma directives.
  298. * -------------------------------------------------------------------------- */
  299. void swig_pragma(char *lang, char *name, char *value) {
  300. if (strcmp(lang,"swig") == 0) {
  301. if ((strcmp(name,"make_default") == 0) || ((strcmp(name,"makedefault") == 0))) {
  302. GenerateDefault = 1;
  303. } else if ((strcmp(name,"no_default") == 0) || ((strcmp(name,"nodefault") == 0))) {
  304. GenerateDefault = 0;
  305. } else if (strcmp(name,"attributefunction") == 0) {
  306. String *nvalue = NewString(value);
  307. char *s = strchr(Char(nvalue),':');
  308. if (!s) {
  309. Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
  310. } else {
  311. *s = 0;
  312. AttributeFunctionGet = NewString(Char(nvalue));
  313. AttributeFunctionSet = NewString(s+1);
  314. }
  315. Delete(nvalue);
  316. } else if (strcmp(name,"noattributefunction") == 0) {
  317. AttributeFunctionGet = 0;
  318. AttributeFunctionSet = 0;
  319. }
  320. }
  321. }
  322. /* ----------------------------------------------------------------------
  323. * Language::top() - Top of parsing tree
  324. * ---------------------------------------------------------------------- */
  325. int Language::top(Node *n) {
  326. return emit_children(n);
  327. }
  328. /* ----------------------------------------------------------------------
  329. * Language::extendDirective()
  330. * ---------------------------------------------------------------------- */
  331. int Language::extendDirective(Node *n) {
  332. int oldam = Extend;
  333. AccessMode oldmode = cplus_mode;
  334. Extend = CWRAP_EXTEND;
  335. cplus_mode = PUBLIC;
  336. emit_children(n);
  337. Extend = oldam;
  338. cplus_mode = oldmode;
  339. return SWIG_OK;
  340. }
  341. /* ----------------------------------------------------------------------
  342. * Language::applyDirective()
  343. * ---------------------------------------------------------------------- */
  344. int Language::applyDirective(Node *n) {
  345. Parm *pattern = Getattr(n,"pattern");
  346. Node *c = firstChild(n);
  347. while (c) {
  348. Parm *apattern = Getattr(c,"pattern");
  349. if (ParmList_len(pattern) != ParmList_len(apattern)) {
  350. Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n",
  351. ParmList_str(pattern), ParmList_str(apattern));
  352. } else {
  353. if (!Swig_typemap_apply(pattern,apattern)) {
  354. Swig_warning(WARN_TYPEMAP_APPLY_UNDEF,input_file,line_number,"Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
  355. }
  356. }
  357. c = nextSibling(c);
  358. }
  359. return SWIG_OK;
  360. }
  361. /* ----------------------------------------------------------------------
  362. * Language::clearDirective()
  363. * ---------------------------------------------------------------------- */
  364. int Language::clearDirective(Node *n) {
  365. Node *p;
  366. for (p = firstChild(n); p; p = nextSibling(p)) {
  367. ParmList *pattern = Getattr(p,"pattern");
  368. Swig_typemap_clear_apply(pattern);
  369. }
  370. return SWIG_OK;
  371. }
  372. /* ----------------------------------------------------------------------
  373. * Language::constantDirective()
  374. * ---------------------------------------------------------------------- */
  375. int Language::constantDirective(Node *n) {
  376. if (CurrentClass && (cplus_mode != PUBLIC)) return SWIG_NOWRAP;
  377. if (!ImportMode) {
  378. Swig_require("constantDirective",n,"name", "?value",NIL);
  379. String *name = Getattr(n,"name");
  380. String *value = Getattr(n,"value");
  381. if (!value) {
  382. value = Copy(name);
  383. } else {
  384. /* if (checkAttribute(n,"type","char")) {
  385. value = NewString(value);
  386. } else {
  387. value = NewStringf("%(escape)s", value);
  388. }
  389. */
  390. Setattr(n,"rawvalue",value);
  391. value = NewStringf("%(escape)s", value);
  392. if (!Len(value)) Append(value,"\\0");
  393. /* Printf(stdout,"'%s' = '%s'\n", name, value); */
  394. }
  395. Setattr(n,"value", value);
  396. this->constantWrapper(n);
  397. Swig_restore(n);
  398. return SWIG_OK;
  399. }
  400. return SWIG_NOWRAP;
  401. }
  402. /* ----------------------------------------------------------------------
  403. * Language::fragmentDirective()
  404. * ---------------------------------------------------------------------- */
  405. int Language::fragmentDirective(Node *n) {
  406. Swig_fragment_register(n);
  407. return SWIG_OK;
  408. }
  409. /* ----------------------------------------------------------------------
  410. * Language::importDirective()
  411. * ---------------------------------------------------------------------- */
  412. int Language::importDirective(Node *n) {
  413. int oldim = ImportMode;
  414. ImportMode = IMPORT_MODE;
  415. emit_children(n);
  416. ImportMode = oldim;
  417. return SWIG_OK;
  418. }
  419. /* ----------------------------------------------------------------------
  420. * Language::includeDirective()
  421. * ---------------------------------------------------------------------- */
  422. int Language::includeDirective(Node *n) {
  423. emit_children(n);
  424. return SWIG_OK;
  425. }
  426. /* ----------------------------------------------------------------------
  427. * Language::insertDirective()
  428. * ---------------------------------------------------------------------- */
  429. int Language::insertDirective(Node *n) {
  430. /* %insert directive */
  431. if ((!ImportMode) || Getattr(n,"generated")) {
  432. String *code = Getattr(n,"code");
  433. String *section = Getattr(n,"section");
  434. File *f = 0;
  435. if (!section) { /* %{ ... %} */
  436. f = Swig_filebyname("header");
  437. } else {
  438. f = Swig_filebyname(section);
  439. }
  440. if (f) {
  441. Printf(f,"%s\n",code);
  442. } else {
  443. Swig_error(input_file,line_number,"Unknown target '%s' for %%insert directive.\n", section);
  444. }
  445. return SWIG_OK;
  446. } else {
  447. return SWIG_NOWRAP;
  448. }
  449. }
  450. /* ----------------------------------------------------------------------
  451. * Language::moduleDirective()
  452. * ---------------------------------------------------------------------- */
  453. int Language::moduleDirective(Node *n) {
  454. (void)n;
  455. /* %module directive */
  456. return SWIG_OK;
  457. }
  458. /* ----------------------------------------------------------------------
  459. * Language::nativeDirective()
  460. * ---------------------------------------------------------------------- */
  461. int Language::nativeDirective(Node *n) {
  462. if (!ImportMode) {
  463. return nativeWrapper(n);
  464. } else {
  465. return SWIG_NOWRAP;
  466. }
  467. }
  468. /* ----------------------------------------------------------------------
  469. * Language::pragmaDirective()
  470. * ---------------------------------------------------------------------- */
  471. int Language::pragmaDirective(Node *n) {
  472. /* %pragma directive */
  473. if (!ImportMode) {
  474. String *lan = Getattr(n,"lang");
  475. String *name = Getattr(n,"name");
  476. String *value = Getattr(n,"value");
  477. swig_pragma(Char(lan),Char(name),Char(value));
  478. /* pragma(Char(lan),Char(name),Char(value)); */
  479. return SWIG_OK;
  480. }
  481. return SWIG_OK;
  482. }
  483. /* ----------------------------------------------------------------------
  484. * Language::typemapDirective()
  485. * ---------------------------------------------------------------------- */
  486. int Language::typemapDirective(Node *n) {
  487. /* %typemap directive */
  488. String *method = Getattr(n,"method");
  489. String *code = Getattr(n,"code");
  490. Parm *kwargs = Getattr(n,"kwargs");
  491. Node *items = firstChild(n);
  492. static int namewarn = 0;
  493. if (code && (Strstr(code,"$source") || (Strstr(code,"$target")))) {
  494. Swig_warning(WARN_TYPEMAP_SOURCETARGET,Getfile(n),Getline(n),"Deprecated typemap feature ($source/$target).\n");
  495. if (!namewarn) {
  496. Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n),
  497. "The use of $source and $target in a typemap declaration is deprecated.\n\
  498. For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
  499. $source by $input and $target by $1. For typemaps related to return values (out,\n\
  500. argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
  501. Doc/Manual/Typemaps.html for complete details.\n");
  502. namewarn = 1;
  503. }
  504. }
  505. if (Strcmp(method,"except") == 0) {
  506. Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n),
  507. "%%typemap(except) is deprecated. Use the %%exception directive.\n");
  508. }
  509. if (Strcmp(method,"in") == 0) {
  510. Hash *k;
  511. k = kwargs;
  512. while (k) {
  513. if (checkAttribute(k,"name","numinputs")) {
  514. if (!multiinput && (GetInt(k,"value") > 1)) {
  515. Swig_error(Getfile(n),Getline(n),"Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
  516. return SWIG_ERROR;
  517. }
  518. break;
  519. }
  520. k = nextSibling(k);
  521. }
  522. if (!k) {
  523. k = NewHash();
  524. Setattr(k,"name","numinputs");
  525. Setattr(k,"value","1");
  526. set_nextSibling(k,kwargs);
  527. Setattr(n,"kwargs",k);
  528. kwargs = k;
  529. }
  530. }
  531. if (Strcmp(method,"ignore") == 0) {
  532. Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n),
  533. "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
  534. Clear(method);
  535. Append(method,"in");
  536. Hash *k = NewHash();
  537. Setattr(k,"name","numinputs");
  538. Setattr(k,"value","0");
  539. set_nextSibling(k,kwargs);
  540. Setattr(n,"kwargs",k);
  541. kwargs = k;
  542. }
  543. /* Replace $descriptor() macros */
  544. if (code) {
  545. Setfile(code,Getfile(n));
  546. Setline(code,Getline(n));
  547. Swig_cparse_replace_descriptor(code);
  548. }
  549. while (items) {
  550. Parm *pattern = Getattr(items,"pattern");
  551. Parm *parms = Getattr(items,"parms");
  552. if (code) {
  553. Swig_typemap_register(method,pattern,code,parms,kwargs);
  554. } else {
  555. Swig_typemap_clear(method,pattern);
  556. }
  557. items = nextSibling(items);
  558. }
  559. return SWIG_OK;
  560. }
  561. /* ----------------------------------------------------------------------
  562. * Language::typemapcopyDirective()
  563. * ---------------------------------------------------------------------- */
  564. int Language::typemapcopyDirective(Node *n) {
  565. String *method = Getattr(n,"method");
  566. Parm *pattern = Getattr(n,"pattern");
  567. Node *items = firstChild(n);
  568. int nsrc = 0;
  569. nsrc = ParmList_len(pattern);
  570. while (items) {
  571. ParmList *npattern = Getattr(items,"pattern");
  572. if (nsrc != ParmList_len(npattern)) {
  573. Swig_error(input_file,line_number,"Can't copy typemap. Number of types differ.\n");
  574. } else {
  575. if (Swig_typemap_copy(method,pattern,npattern) < 0) {
  576. Swig_error(input_file, line_number, "Can't copy typemap.\n");
  577. }
  578. }
  579. items = nextSibling(items);
  580. }
  581. return SWIG_OK;
  582. }
  583. /* ----------------------------------------------------------------------
  584. * Language::typesDirective()
  585. * ---------------------------------------------------------------------- */
  586. int Language::typesDirective(Node *n) {
  587. Parm *parms = Getattr(n,"parms");
  588. while (parms) {
  589. SwigType *t = Getattr(parms,"type");
  590. String *v = Getattr(parms,"value");
  591. if (!v) {
  592. SwigType_remember(t);
  593. } else {
  594. if (SwigType_issimple(t)) {
  595. SwigType_inherit(t,v,0);
  596. }
  597. }
  598. parms = nextSibling(parms);
  599. }
  600. return SWIG_OK;
  601. }
  602. /* ----------------------------------------------------------------------
  603. * Language::cDeclaration()
  604. * ---------------------------------------------------------------------- */
  605. int Language::cDeclaration(Node *n) {
  606. String *name = Getattr(n,"name");
  607. String *symname = Getattr(n,"sym:name");
  608. SwigType *type = Getattr(n,"type");
  609. SwigType *decl = Getattr(n,"decl");
  610. String *storage = Getattr(n,"storage");
  611. Node *over;
  612. File *f_header = 0;
  613. SwigType *ty, *fullty;
  614. /* discarts nodes following the access control rules */
  615. if (cplus_mode != PUBLIC || !is_public(n)) {
  616. /* except for friends, they are not affected by access control */
  617. int isfriend = storage && (Cmp(storage,"friend") == 0);
  618. if (!isfriend ) {
  619. /* we check what director needs. If the method is pure virtual,
  620. it is always needed. */
  621. if (!(directorsEnabled() && is_member_director(CurrentClass,n) && need_nonpublic_member(n)))
  622. return SWIG_NOWRAP;
  623. }
  624. }
  625. if (Cmp(storage,"typedef") == 0) {
  626. Swig_save("cDeclaration",n,"type",NIL);
  627. SwigType *t = Copy(type);
  628. if (t) {
  629. SwigType_push(t,decl);
  630. Setattr(n,"type",t);
  631. typedefHandler(n);
  632. }
  633. Swig_restore(n);
  634. return SWIG_OK;
  635. }
  636. /* If in import mode, we proceed no further */
  637. if (ImportMode) return SWIG_NOWRAP;
  638. /* If we're in extend mode and there is code, replace the $descriptor macros */
  639. if (Getattr(n,"feature:extend")) {
  640. String *code = Getattr(n,"code");
  641. if (code) {
  642. Setfile(code,Getfile(n));
  643. Setline(code,Getline(n));
  644. Swig_cparse_replace_descriptor(code);
  645. }
  646. }
  647. /* Overloaded symbol check */
  648. over = Swig_symbol_isoverloaded(n);
  649. if (!overloading) {
  650. if (over) over = first_nontemplate(over);
  651. if (over && (over != n)) {
  652. SwigType *tc = Copy(decl);
  653. SwigType *td = SwigType_pop_function(tc);
  654. String *oname;
  655. String *cname;
  656. if (CurrentClass) {
  657. oname = NewStringf("%s::%s",ClassName,name);
  658. cname = NewStringf("%s::%s",ClassName,Getattr(over,"name"));
  659. } else {
  660. oname = NewString(name);
  661. cname = NewString(Getattr(over,"name"));
  662. }
  663. SwigType *tc2 = Copy(Getattr(over,"decl"));
  664. SwigType *td2 = SwigType_pop_function(tc2);
  665. Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", SwigType_str(td,SwigType_namestr(oname)));
  666. Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over),"Previous declaration is %s\n", SwigType_str(td2,SwigType_namestr(cname)));
  667. Delete(tc2);
  668. Delete(td2);
  669. Delete(tc);
  670. Delete(td);
  671. Delete(oname);
  672. Delete(cname);
  673. return SWIG_NOWRAP;
  674. }
  675. }
  676. if (symname && !validIdentifier(symname)) {
  677. Swig_warning(WARN_LANG_IDENTIFIER,input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n",
  678. symname);
  679. return SWIG_NOWRAP;
  680. }
  681. ty = NewString(type);
  682. SwigType_push(ty,decl);
  683. fullty = SwigType_typedef_resolve_all(ty);
  684. if (SwigType_isfunction(fullty)) {
  685. if (!SwigType_isfunction(ty)) {
  686. Delete(ty);
  687. ty = fullty;
  688. fullty = 0;
  689. ParmList *parms = SwigType_function_parms(ty);
  690. Setattr(n,"parms",parms);
  691. }
  692. /* Transform the node into a 'function' node and emit */
  693. if (!CurrentClass) {
  694. f_header = Swig_filebyname("header");
  695. if (AddExtern) {
  696. if (f_header) {
  697. if ((Cmp(storage,"extern") == 0) || (ForceExtern && !storage)) {
  698. /* we don't need the 'extern' part in the C/C++ declaration,
  699. and it produces some problems when namespace and SUN
  700. Studio is used.
  701. Printf(f_header,"extern %s", SwigType_str(ty,name));
  702. In fact generating extern declarations is quite error prone and is
  703. no longer the default. Getting it right seems impossible with namespaces
  704. and default arguments and when a method is declared with the various Windows
  705. calling conventions - SWIG doesn't understand Windows (non standard) calling
  706. conventions in the first place, so can't regenerate them.
  707. */
  708. String *str = SwigType_str(ty,name);
  709. Printf(f_header,"%s", str);
  710. Delete(str);
  711. {
  712. DOH *t = Getattr(n,"throws");
  713. if (t) {
  714. Printf(f_header," throw(");
  715. while (t) {
  716. Printf(f_header,"%s", Getattr(t,"type"));
  717. t = nextSibling(t);
  718. if (t) Printf(f_header,",");
  719. }
  720. Printf(f_header,")");
  721. }
  722. }
  723. Printf(f_header,";\n");
  724. } else if (Cmp(storage,"externc") == 0) {
  725. /* here 'extern "C"' is needed */
  726. String *str = SwigType_str(ty,name);
  727. Printf(f_header, "extern \"C\" %s;\n", str);
  728. Delete(str);
  729. }
  730. }
  731. }
  732. }
  733. /* This needs to check qualifiers */
  734. if (SwigType_isqualifier(ty)) {
  735. SwigType *qual = SwigType_pop(ty);
  736. Setattr(n,"qualifier", qual);
  737. Delete(qual);
  738. }
  739. Delete(SwigType_pop_function(ty));
  740. DohIncref(type);
  741. Setattr(n,"type",ty);
  742. functionHandler(n);
  743. Setattr(n,"type",type);
  744. Delete(ty);
  745. Delete(type);
  746. return SWIG_OK;
  747. } else {
  748. /* Some kind of variable declaration */
  749. Delattr(n,"decl");
  750. if (Getattr(n,"nested")) SetFlag(n,"feature:immutable");
  751. if (!CurrentClass) {
  752. if ((Cmp(storage,"extern") == 0) || ForceExtern) {
  753. f_header = Swig_filebyname("header");
  754. if (AddExtern) {
  755. if (f_header) {
  756. String *str = SwigType_str(ty,name);
  757. Printf(f_header,"extern %s;\n", str);
  758. Delete(str);
  759. }
  760. }
  761. }
  762. }
  763. if (!SwigType_ismutable(ty)) {
  764. SetFlag(n,"feature:immutable");
  765. }
  766. /* If an array and elements are const, then read-only */
  767. if (SwigType_isarray(ty)) {
  768. SwigType *tya = SwigType_array_type(ty);
  769. if (SwigType_isconst(tya)) {
  770. SetFlag(n,"feature:immutable");
  771. }
  772. Delete(tya);
  773. }
  774. DohIncref(type);
  775. Setattr(n,"type",ty);
  776. variableHandler(n);
  777. Setattr(n,"type",type);
  778. Setattr(n,"decl",decl);
  779. Delete(ty);
  780. Delete(type);
  781. Delete(fullty);
  782. return SWIG_OK;
  783. }
  784. }
  785. /* ----------------------------------------------------------------------
  786. * Language::functionHandler()
  787. * ---------------------------------------------------------------------- */
  788. int
  789. Language::functionHandler(Node *n) {
  790. Parm *p;
  791. p = Getattr(n,"parms");
  792. if (!CurrentClass) {
  793. globalfunctionHandler(n);
  794. } else {
  795. String *storage = Getattr(n,"storage");
  796. if (Cmp(storage,"static") == 0 &&
  797. !(SmartPointer && Getattr(n,"allocate:smartpointeraccess"))) {
  798. staticmemberfunctionHandler(n);
  799. } else if (Cmp(storage,"friend") == 0) {
  800. globalfunctionHandler(n);
  801. } else {
  802. memberfunctionHandler(n);
  803. }
  804. }
  805. return SWIG_OK;
  806. }
  807. /* ----------------------------------------------------------------------
  808. * Language::globalfunctionHandler()
  809. * ---------------------------------------------------------------------- */
  810. int
  811. Language::globalfunctionHandler(Node *n) {
  812. Swig_require("globalfunctionHandler",n,"name","sym:name","type","?parms",NIL);
  813. String *name = Getattr(n,"name");
  814. String *symname = Getattr(n,"sym:name");
  815. SwigType *type = Getattr(n,"type");
  816. String *storage = Getattr(n,"storage");
  817. ParmList *parms = Getattr(n,"parms");
  818. if (0 && (Cmp(storage,"static") == 0)) {
  819. Swig_restore(n);
  820. return SWIG_NOWRAP; /* Can't wrap static functions */
  821. } else {
  822. /* Check for callback mode */
  823. String *cb = GetFlagAttr(n,"feature:callback");
  824. if (cb) {
  825. String *cbname = Getattr(n,"feature:callback:name");
  826. if (!cbname) {
  827. cbname = NewStringf(cb,symname);
  828. Setattr(n,"feature:callback:name",cbname);
  829. }
  830. callbackfunctionHandler(n);
  831. if (Cmp(cbname, symname) == 0) {
  832. Delete(cbname);
  833. Swig_restore(n);
  834. return SWIG_NOWRAP;
  835. }
  836. Delete(cbname);
  837. }
  838. Setattr(n,"parms",nonvoid_parms(parms));
  839. Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(name,parms)));
  840. functionWrapper(n);
  841. }
  842. Swig_restore(n);
  843. return SWIG_OK;
  844. }
  845. /* ----------------------------------------------------------------------
  846. * Language::callbackfunctionHandler()
  847. * ---------------------------------------------------------------------- */
  848. int
  849. Language::callbackfunctionHandler(Node *n) {
  850. Swig_require("callbackfunctionHandler",n,"name","*sym:name","*type","?value",NIL);
  851. String *symname = Getattr(n,"sym:name");
  852. String *type = Getattr(n,"type");
  853. String *name = Getattr(n,"name");
  854. String *parms = Getattr(n,"parms");
  855. String *cb = GetFlagAttr(n,"feature:callback");
  856. String *cbname = Getattr(n,"feature:callback:name");
  857. String *calltype= NewStringf("(%s (*)(%s))(%s)", SwigType_str(type,0), ParmList_str(parms), SwigType_namestr(name));
  858. SwigType *cbty = Copy(type);
  859. SwigType_add_function(cbty,parms);
  860. SwigType_add_pointer(cbty);
  861. if (!cbname) {
  862. cbname = NewStringf(cb,symname);
  863. Setattr(n,"feature:callback:name",cbname);
  864. }
  865. Setattr(n,"sym:name", cbname);
  866. Setattr(n,"type", cbty);
  867. Setattr(n,"value", calltype);
  868. Node *ns = Getattr(symbols,cbname);
  869. if (!ns) constantWrapper(n);
  870. Delete(cbname);
  871. Delete(cbty);
  872. Swig_restore(n);
  873. return SWIG_OK;
  874. }
  875. /* ----------------------------------------------------------------------
  876. * Language::memberfunctionHandler()
  877. * ---------------------------------------------------------------------- */
  878. int
  879. Language::memberfunctionHandler(Node *n) {
  880. Swig_require("memberfunctionHandler",n,"*name","*sym:name","*type","?parms","?value",NIL);
  881. String *storage = Getattr(n,"storage");
  882. String *name = Getattr(n,"name");
  883. String *symname = Getattr(n,"sym:name");
  884. SwigType *type = Getattr(n,"type");
  885. String *value = Getattr(n,"value");
  886. ParmList *parms = Getattr(n,"parms");
  887. String *cb = GetFlagAttr(n,"feature:callback");
  888. if (Cmp(storage,"virtual") == 0) {
  889. if (Cmp(value,"0") == 0) {
  890. IsVirtual = PURE_VIRTUAL;
  891. } else {
  892. IsVirtual = PLAIN_VIRTUAL;
  893. }
  894. } else {
  895. IsVirtual = 0;
  896. }
  897. if (cb) {
  898. Node *cbn = NewHash();
  899. String *cbname = Getattr(n,"feature:callback:name");
  900. if (!cbname) {
  901. cbname = NewStringf(cb,symname);
  902. }
  903. SwigType *cbty = Copy(type);
  904. SwigType_add_function(cbty,parms);
  905. SwigType_add_memberpointer(cbty,ClassName);
  906. String *cbvalue = NewStringf("&%s::%s",ClassName,name);
  907. Setattr(cbn,"sym:name", cbname);
  908. Setattr(cbn,"type", cbty);
  909. Setattr(cbn,"value", cbvalue);
  910. Setattr(cbn,"name", name);
  911. memberconstantHandler(cbn);
  912. Setattr(n,"feature:callback:name",Swig_name_member(ClassPrefix, cbname));
  913. Delete(cb);
  914. Delete(cbn);
  915. Delete(cbvalue);
  916. Delete(cbty);
  917. Delete(cbname);
  918. if (Cmp(cbname,symname) == 0) {
  919. Swig_restore(n);
  920. return SWIG_NOWRAP;
  921. }
  922. }
  923. String *fname = Swig_name_member(ClassPrefix, symname);
  924. if (Extend && SmartPointer) {
  925. if (!Getattr(n,"classname")) {
  926. Setattr(n,"classname",Getattr(CurrentClass,"allocate:smartpointerbase"));
  927. }
  928. }
  929. /* Transformation */
  930. Swig_MethodToFunction(n,ClassType, Getattr(n,"template") ? 0 : Extend | SmartPointer);
  931. Setattr(n,"sym:name",fname);
  932. functionWrapper(n);
  933. /* DelWrapper(w);*/
  934. Delete(fname);
  935. Swig_restore(n);
  936. return SWIG_OK;
  937. }
  938. /* ----------------------------------------------------------------------
  939. * Language::staticmemberfunctionHandler()
  940. * ---------------------------------------------------------------------- */
  941. int
  942. Language::staticmemberfunctionHandler(Node *n) {
  943. Swig_require("staticmemberfunctionHandler",n,"*name","*sym:name","*type",NIL);
  944. Swig_save("staticmemberfunctionHandler",n,"storage",NIL);
  945. String *name = Getattr(n,"name");
  946. String *symname = Getattr(n,"sym:name");
  947. SwigType *type = Getattr(n,"type");
  948. ParmList *parms = Getattr(n,"parms");
  949. String *cb = GetFlagAttr(n,"feature:callback");
  950. String *cname, *mrename;
  951. if (!Extend) {
  952. Node *sb = Getattr(n,"cplus:staticbase");
  953. String *sname = sb ? Getattr(sb,"name") : 0;
  954. if (sname) {
  955. cname = NewStringf("%s::%s",sname,name);
  956. } else {
  957. cname = NewStringf("%s::%s",ClassName,name);
  958. }
  959. } else {
  960. String *mname = Swig_name_mangle(ClassName);
  961. cname = Swig_name_member(mname,name);
  962. Delete(mname);
  963. }
  964. mrename = Swig_name_member(ClassPrefix, symname);
  965. if (Extend) {
  966. String *code = Getattr(n,"code");
  967. String *defaultargs = Getattr(n,"defaultargs");
  968. String *mangled = Swig_name_mangle(mrename);
  969. Delete(mrename);
  970. mrename = mangled;
  971. if (Getattr(n,"sym:overloaded") && code) {
  972. Append(cname, Getattr(defaultargs ? defaultargs : n,"sym:overname"));
  973. }
  974. if (!defaultargs && code) {
  975. /* Hmmm. An added static member. We have to create a little wrapper for this */
  976. Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus);
  977. }
  978. }
  979. Setattr(n,"name",cname);
  980. Setattr(n,"sym:name",mrename);
  981. if (cb) {
  982. String *cbname = NewStringf(cb,symname);
  983. Setattr(n,"feature:callback:name", Swig_name_member(ClassPrefix, cbname));
  984. Setattr(n,"feature:callback:staticname", name);
  985. }
  986. Delattr(n,"storage");
  987. globalfunctionHandler(n);
  988. Delete(cname);
  989. Delete(mrename);
  990. Swig_restore(n);
  991. return SWIG_OK;
  992. }
  993. /* ----------------------------------------------------------------------
  994. * Language::variableHandler()
  995. * ---------------------------------------------------------------------- */
  996. int
  997. Language::variableHandler(Node *n) {
  998. if (!CurrentClass) {
  999. globalvariableHandler(n);
  1000. } else {
  1001. String *storage = Getattr(n,"storage");
  1002. Swig_save("variableHandler",n,"feature:immutable",NIL);
  1003. if (SmartPointer) {
  1004. /* If a smart-pointer and it's a constant access, we have to set immutable */
  1005. if (Getattr(CurrentClass,"allocate:smartpointerconst")) {
  1006. SetFlag(n,"feature:immutable");
  1007. }
  1008. }
  1009. if ((Cmp(storage,"static") == 0)
  1010. && !(SmartPointer && Getattr(n,"allocate:smartpointeraccess"))) {
  1011. staticmembervariableHandler(n);
  1012. } else {
  1013. membervariableHandler(n);
  1014. }
  1015. Swig_restore(n);
  1016. }
  1017. return SWIG_OK;
  1018. }
  1019. /* ----------------------------------------------------------------------
  1020. * Language::globalvariableHandler()
  1021. * ---------------------------------------------------------------------- */
  1022. int
  1023. Language::globalvariableHandler(Node *n) {
  1024. String *storage = Getattr(n,"storage");
  1025. if (0 && (Cmp(storage,"static") == 0)) return SWIG_NOWRAP;
  1026. variableWrapper(n);
  1027. return SWIG_OK;
  1028. }
  1029. /* ----------------------------------------------------------------------
  1030. * Language::membervariableHandler()
  1031. * ---------------------------------------------------------------------- */
  1032. int
  1033. Language::membervariableHandler(Node *n) {
  1034. Swig_require("membervariableHandler",n,"*name","*sym:name","*type",NIL);
  1035. Swig_save("membervariableHandler",n,"parms",NIL);
  1036. String *name = Getattr(n,"name");
  1037. String *symname = Getattr(n,"sym:name");
  1038. SwigType *type = Getattr(n,"type");
  1039. /* If not a smart-pointer access or added method. We clear
  1040. feature:except. There is no way C++ or C would throw
  1041. an exception merely for accessing a member data.
  1042. Caveat: Some compilers seem to route attribute access through
  1043. methods which can generate exceptions. The feature:allowexcept
  1044. allows this.
  1045. */
  1046. if (!(Extend | SmartPointer) && (!GetFlag(n,"feature:allowexcept"))) {
  1047. UnsetFlag(n,"feature:except");
  1048. }
  1049. if (!AttributeFunctionGet) {
  1050. String *mrename_get, *mrename_set;
  1051. mrename_get = Swig_name_get(Swig_name_member(ClassPrefix, symname));
  1052. mrename_set = Swig_name_set(Swig_name_member(ClassPrefix, symname));
  1053. /* Create a function to set the value of the variable */
  1054. int assignable = is_assignable(n);
  1055. if (SmartPointer) {
  1056. if (Getattr(CurrentClass,"allocate:smartpointerconst")) {
  1057. assignable = 0;
  1058. }
  1059. }
  1060. if (assignable) {
  1061. int make_set_wrapper = 1;
  1062. String *tm = 0;
  1063. String *target = 0;
  1064. if (!Extend) {
  1065. if (SmartPointer) {
  1066. if (checkAttribute(n, "storage", "static")) {
  1067. Node *sn = Getattr(n,"cplus:staticbase");
  1068. String *base = Getattr(sn,"name");
  1069. target = NewStringf("%s::%s", base,name);
  1070. } else {
  1071. target = NewStringf("(*%s)->%s",Swig_cparm_name(0,0),name);
  1072. }
  1073. } else {
  1074. target = NewStringf("%s->%s", Swig_cparm_name(0,0),name);
  1075. }
  1076. tm = Swig_typemap_lookup_new("memberin",n,target,0);
  1077. }
  1078. int flags = Extend | SmartPointer;
  1079. //if (CPlusPlus) flags |= CWRAP_VAR_REFERENCE;
  1080. Swig_MembersetToFunction(n,ClassType, flags);
  1081. if (!Extend) {
  1082. /* Check for a member in typemap here */
  1083. if (!tm) {
  1084. if (SwigType_isarray(type)) {
  1085. Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number,
  1086. "Unable to set variable of type %s.\n", SwigType_str(type,0));
  1087. make_set_wrapper = 0;
  1088. }
  1089. } else {
  1090. Replace(tm,"$source", Swig_cparm_name(0,1), DOH_REPLACE_ANY);
  1091. Replace(tm,"$target", target, DOH_REPLACE_ANY);
  1092. Replace(tm,"$input",Swig_cparm_name(0,1),DOH_REPLACE_ANY);
  1093. Replace(tm,"$self",Swig_cparm_name(0,0),DOH_REPLACE_ANY);
  1094. Setattr(n,"wrap:action", tm);
  1095. Delete(tm);
  1096. }
  1097. Delete(target);
  1098. }
  1099. if (make_set_wrapper) {
  1100. Setattr(n,"sym:name", mrename_set);
  1101. functionWrapper(n);
  1102. } else {
  1103. SetFlag(n,"feature:immutable");
  1104. }
  1105. /* Restore parameters */
  1106. Setattr(n,"type",type);
  1107. Setattr(n,"name",name);
  1108. Setattr(n,"sym:name",symname);
  1109. /* Delete all attached typemaps and typemap attributes */
  1110. Iterator ki;
  1111. for (ki = First(n); ki.key; ki = Next(ki)) {
  1112. if (Strncmp(ki.key, "tmap:", 5) == 0)
  1113. Delattr(n, ki.key);
  1114. }
  1115. }
  1116. /* Emit get function */
  1117. {
  1118. Swig_MembergetToFunction(n,ClassType, Extend | SmartPointer);
  1119. Setattr(n,"sym:name", mrename_get);
  1120. functionWrapper(n);
  1121. }
  1122. Delete(mrename_get);
  1123. Delete(mrename_set);
  1124. } else {
  1125. /* This code is used to support the attributefunction directive
  1126. where member variables are converted automagically to
  1127. accessor functions */
  1128. #if 0
  1129. Parm *p;
  1130. String *gname;
  1131. SwigType *vty;
  1132. p = NewParm(type,0);
  1133. gname = NewStringf(AttributeFunctionGet,symname);
  1134. if (!Extend) {
  1135. ActionFunc = Copy(Swig_cmemberget_call(name,type));
  1136. cpp_member_func(Char(gname),Char(gname),type,0);
  1137. Delete(ActionFunc);
  1138. } else {
  1139. String *cname = Copy(Swig_name_get(name));
  1140. cpp_member_func(Char(cname),Char(gname),type,0);
  1141. Delete(cname);
  1142. }
  1143. Delete(gname);
  1144. if (!GetFlag(n,"feature:immutable")) {
  1145. gname = NewStringf(AttributeFunctionSet,symname);
  1146. vty = NewString("void");
  1147. if (!Extend) {
  1148. ActionFunc = Copy(Swig_cmemberset_call(name,type));
  1149. cpp_member_func(Char(gname),Char(gname),vty,p);
  1150. Delete(ActionFunc);
  1151. } else {
  1152. String *cname = Copy(Swig_name_set(name));
  1153. cpp_member_func(Char(cname),Char(gname),vty,p);
  1154. Delete(cname);
  1155. }
  1156. Delete(gname);
  1157. }
  1158. ActionFunc = 0;
  1159. #endif
  1160. }
  1161. Swig_restore(n);
  1162. return SWIG_OK;
  1163. }
  1164. /* ----------------------------------------------------------------------
  1165. * Language::staticmembervariableHandler()
  1166. * ---------------------------------------------------------------------- */
  1167. int
  1168. Language::staticmembervariableHandler(Node *n)
  1169. {
  1170. Swig_require("staticmembervariableHandler",n,"*name","*sym:name","*type", "?value", NIL);
  1171. String *value = Getattr(n,"value");
  1172. SwigType *type = SwigType_typedef_resolve_all(Getattr(n,"type"));
  1173. String *classname = !SmartPointer ? ClassName : Getattr(CurrentClass,"allocate:smartpointerbase");
  1174. if (!value || !(SwigType_isconst(type))) {
  1175. String *name = Getattr(n,"name");
  1176. String *symname = Getattr(n,"sym:name");
  1177. String *cname, *mrename;
  1178. /* Create the variable name */
  1179. mrename = Swig_name_member(ClassPrefix, symname);
  1180. cname = NewStringf("%s::%s", classname,name);
  1181. Setattr(n,"sym:name",mrename);
  1182. Setattr(n,"name", cname);
  1183. /* Wrap as an ordinary global variable */
  1184. variableWrapper(n);
  1185. Delete(mrename);
  1186. Delete(cname);
  1187. } else {
  1188. /* This is a C++ static member declaration with an initializer and it's const.
  1189. Certain C++ compilers optimize this out so that there is no linkage to a
  1190. memory address. Example:
  1191. class Foo {
  1192. public:
  1193. static const int x = 3;
  1194. };
  1195. Some discussion of this in section 9.4 of the C++ draft standard. */
  1196. String *name = Getattr(n,"name");
  1197. String *cname = NewStringf("%s::%s", classname,name);
  1198. String* value = SwigType_namestr(cname);
  1199. Setattr(n, "value", value);
  1200. SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n,"type"));
  1201. SwigType *t2 = SwigType_strip_qualifiers(t1);
  1202. Setattr(n, "type", t2);
  1203. Delete(t1);
  1204. Delete(t2);
  1205. memberconstantHandler(n);
  1206. Delete(cname);
  1207. }
  1208. Delete(type);
  1209. Swig_restore(n);
  1210. return SWIG_OK;
  1211. }
  1212. /* ----------------------------------------------------------------------
  1213. * Language::externDeclaration()
  1214. * ---------------------------------------------------------------------- */
  1215. int Language::externDeclaration(Node *n) {
  1216. return emit_children(n);
  1217. }
  1218. /* ----------------------------------------------------------------------
  1219. * Language::enumDeclaration()
  1220. * ---------------------------------------------------------------------- */
  1221. int Language::enumDeclaration(Node *n) {
  1222. if (!ImportMode) {
  1223. emit_children(n);
  1224. }
  1225. return SWIG_OK;
  1226. }
  1227. /* ----------------------------------------------------------------------
  1228. * Language::enumvalueDeclaration()
  1229. * ---------------------------------------------------------------------- */
  1230. int Language::enumvalueDeclaration(Node *n) {
  1231. if (CurrentClass && (cplus_mode != PUBLIC)) return SWIG_NOWRAP;
  1232. Swig_require("enumvalueDeclaration",n,"*name", "?value",NIL);
  1233. String *value = Getattr(n,"value");
  1234. String *name = Getattr(n,"name");
  1235. String *tmpValue;
  1236. if (value)
  1237. tmpValue = NewString(value);
  1238. else
  1239. tmpValue = NewString(name);
  1240. Setattr(n, "value", tmpValue);
  1241. if (!CurrentClass) {
  1242. Setattr(n,"name",tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
  1243. constantWrapper(n);
  1244. } else {
  1245. memberconstantHandler(n);
  1246. }
  1247. Delete(tmpValue);
  1248. Swig_restore(n);
  1249. return SWIG_OK;
  1250. }
  1251. /* ----------------------------------------------------------------------
  1252. * Language::enumforwardDeclaration()
  1253. * ---------------------------------------------------------------------- */
  1254. int Language::enumforwardDeclaration(Node *n) {
  1255. (void)n;
  1256. return SWIG_OK;
  1257. }
  1258. /* -----------------------------------------------------------------------------
  1259. * Language::memberconstantHandler()
  1260. * ----------------------------------------------------------------------------- */
  1261. int Language::memberconstantHandler(Node *n) {
  1262. Swig_require("memberconstantHandler",n,"*name","*sym:name","*value",NIL);
  1263. String *name = Getattr(n,"name");
  1264. String *symname = Getattr(n,"sym:name");
  1265. String *value = Getattr(n,"value");
  1266. String *mrename;
  1267. String *new_value;
  1268. mrename = Swig_name_member(ClassPrefix, symname);
  1269. /* Fixed by namespace-enum patch
  1270. if ((!value) || (Cmp(value,name) == 0)) {
  1271. new_value = NewStringf("%s::%s",ClassName,name);
  1272. } else {
  1273. new_value = NewString(value);
  1274. }
  1275. */
  1276. new_value = Copy(value);
  1277. Setattr(n,"sym:name", mrename);
  1278. Setattr(n,"value", new_value);
  1279. Setattr(n,"name", NewStringf("%s::%s", ClassName,name));
  1280. constantWrapper(n);
  1281. Delete(mrename);
  1282. Delete(new_value);
  1283. Swig_restore(n);
  1284. return SWIG_OK;
  1285. }
  1286. /* ----------------------------------------------------------------------
  1287. * Language::typedefHandler()
  1288. * ---------------------------------------------------------------------- */
  1289. int Language::typedefHandler(Node *n) {
  1290. /* since this is a recurring issue, we are going to remember the
  1291. typedef pointer, if already it is not a pointer or reference, as
  1292. in
  1293. typedef void NT;
  1294. int func(NT *p);
  1295. see director_basic.i for example.
  1296. */
  1297. SwigType *name = Getattr(n,"name");
  1298. SwigType *decl = Getattr(n,"decl");
  1299. if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
  1300. SwigType *pname = Copy(name);
  1301. SwigType_add_pointer(pname);
  1302. SwigType_remember(pname);
  1303. Delete(pname);
  1304. }
  1305. return SWIG_OK;
  1306. }
  1307. /* ----------------------------------------------------------------------
  1308. * Language::classDirectorMethod()
  1309. * ---------------------------------------------------------------------- */
  1310. int Language::classDirectorMethod(Node *n, Node *parent, String* super) {
  1311. (void)n;
  1312. (void)parent;
  1313. (void)super;
  1314. return SWIG_OK;
  1315. }
  1316. /* ----------------------------------------------------------------------
  1317. * Language::classDirectorConstructor()
  1318. * ---------------------------------------------------------------------- */
  1319. int Language::classDirectorConstructor(Node *n) {
  1320. (void)n;
  1321. return SWIG_OK;
  1322. }
  1323. /* ----------------------------------------------------------------------
  1324. * Language::classDirectorDefaultConstructor()
  1325. * ---------------------------------------------------------------------- */
  1326. int Language::classDirectorDefaultConstructor(Node *n) {
  1327. (void)n;
  1328. return SWIG_OK;
  1329. }
  1330. static
  1331. String *vtable_method_id(Node *n)
  1332. {
  1333. String *nodeType = Getattr(n, "nodeType");
  1334. int is_destructor = (Cmp(nodeType, "destructor") == 0);
  1335. if (is_destructor) return 0;
  1336. String *name = Getattr(n, "name");
  1337. String *decl = Getattr(n, "decl");
  1338. String *local_decl = SwigType_typedef_resolve_all(decl);
  1339. Node *method_id = NewStringf("%s|%s", name, local_decl);
  1340. Delete(local_decl);
  1341. return method_id;
  1342. }
  1343. /* ----------------------------------------------------------------------
  1344. * Language::unrollVirtualMethods()
  1345. * ---------------------------------------------------------------------- */
  1346. int Language::unrollVirtualMethods(Node *n,
  1347. Node *parent,
  1348. Hash *vm,
  1349. int default_director,
  1350. int &virtual_destructor,
  1351. int protectedbase) {
  1352. Node *ni;
  1353. String *nodeType;
  1354. String *classname;
  1355. String *decl;
  1356. bool first_base = false;
  1357. // recurse through all base classes to build the vtable
  1358. List* bl = Getattr(n, "bases");
  1359. if (bl) {
  1360. Iterator bi;
  1361. for (bi = First(bl); bi.item; bi = Next(bi)) {
  1362. if (first_base && !director_multiple_inheritance) break;
  1363. unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
  1364. first_base = true;
  1365. }
  1366. }
  1367. // recurse through all protected base classes to build the vtable, as needed
  1368. bl = Getattr(n, "protectedbases");
  1369. if (bl) {
  1370. Iterator bi;
  1371. for (bi = First(bl); bi.item; bi = Next(bi)) {
  1372. if (first_base && !director_multiple_inheritance) break;
  1373. unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
  1374. first_base = true;
  1375. }
  1376. }
  1377. // find the methods that need directors
  1378. classname = Getattr(n, "name");
  1379. for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
  1380. /* we only need to check the virtual members */
  1381. if (!checkAttribute(ni, "storage", "virtual")) continue;
  1382. nodeType = Getattr(ni, "nodeType");
  1383. /* we need to add methods(cdecl) and destructor (to check for throw decl) */
  1384. int is_destructor = (Cmp(nodeType, "destructor") == 0);
  1385. if ((Cmp(nodeType, "cdecl") == 0)|| is_destructor) {
  1386. decl = Getattr(ni, "decl");
  1387. /* extra check for function type and proper access */
  1388. if (SwigType_isfunction(decl)
  1389. && (((!protectedbase || dirprot_mode()) && is_public(ni))
  1390. || need_nonpublic_member(ni))) {
  1391. String *name = Getattr(ni, "name");
  1392. Node *method_id = is_destructor ?
  1393. NewStringf("~destructor") : vtable_method_id(ni);
  1394. /* Make sure that the new method overwrites the existing: */
  1395. Hash *exists_item = Getattr(vm, method_id);
  1396. if (exists_item) {
  1397. /* maybe we should check for precedence here, ie, only
  1398. delete the previous method if 'n' is derived from the
  1399. previous method parent node. This is almost always true,
  1400. so by now, we just delete the entry. */
  1401. Delattr(vm, method_id);
  1402. }
  1403. /* filling a new method item */
  1404. String *fqdname = NewStringf("%s::%s", classname, name);
  1405. Hash *item = NewHash();
  1406. Setattr(item, "fqdname", fqdname);
  1407. Node *m = Copy(ni);
  1408. /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
  1409. SwigType *ty = NewString(Getattr(m,"type"));
  1410. SwigType_push(ty,decl);
  1411. if (SwigType_isqualifier(ty)) {
  1412. Delete(SwigType_pop(ty));
  1413. }
  1414. Delete(SwigType_pop_function(ty));
  1415. Setattr(m,"returntype", ty);
  1416. String *mname = NewStringf("%s::%s", Getattr(parent,"name"),name);
  1417. /* apply the features of the original method found in the base class */
  1418. Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m,"decl"), m);
  1419. Setattr(item, "methodNode", m);
  1420. Setattr(vm, method_id, item);
  1421. Delete(mname);
  1422. Delete(fqdname);
  1423. Delete(item);
  1424. Delete(method_id);
  1425. }
  1426. if (is_destructor) {
  1427. virtual_destructor = 1;
  1428. }
  1429. }
  1430. }
  1431. /*
  1432. We delete all the nodirector methods. This prevents the
  1433. generation of 'empty' director classes.
  1434. But this has to be done outside the previous 'for'
  1435. an the recursive loop!.
  1436. */
  1437. if (n == parent) {
  1438. Iterator k;
  1439. for (k = First(vm); k.key; k = Next(k)) {
  1440. Node *m = Getattr(k.item, "methodNode");
  1441. /* retrieve the director features */
  1442. int mdir = GetFlag(m, "feature:director");
  1443. int mndir = GetFlag(m, "feature:nodirector");
  1444. /* 'nodirector' has precedence over 'director' */
  1445. int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
  1446. /* check if the method was found only in a base class */
  1447. Node *p = Getattr(m, "parentNode");
  1448. if (p != n) {
  1449. Node *c = Copy(m);
  1450. Setattr(c, "parentNode", n);
  1451. int cdir = GetFlag(c, "feature:director");
  1452. int cndir = GetFlag(c, "feature:nodirector");
  1453. dir = (cdir || cndir) ? (cdir && !cndir) : dir;
  1454. Delete(c);
  1455. }
  1456. if (dir) {
  1457. /* be sure the 'nodirector' feature is disabled */
  1458. if (mndir) Delattr(m, "feature:nodirector");
  1459. } else {
  1460. /* or just delete from the vm, since is not a director method */
  1461. Delattr(vm, k.key);
  1462. }
  1463. }
  1464. }
  1465. return SWIG_OK;
  1466. }
  1467. /* ----------------------------------------------------------------------
  1468. * Language::classDirectorDisown()
  1469. * ---------------------------------------------------------------------- */
  1470. int Language::classDirectorDisown(Node *n) {
  1471. Node *disown = NewHash();
  1472. String *mrename;
  1473. String *symname = Getattr(n,"sym:name");
  1474. mrename = Swig_name_disown(symname); //Getattr(n, "name"));
  1475. String *type = NewString(ClassType);
  1476. String *name = NewString("self");
  1477. SwigType_add_pointer(type);
  1478. Parm *p = NewParm(type, name);
  1479. Delete(name);
  1480. Delete(type);
  1481. type = NewString("void");
  1482. String *action = NewString("");
  1483. Printv(action, "{\n",
  1484. "Swig::Director *director = dynamic_cast<Swig::Director *>(arg1);\n",
  1485. "if (director) director->swig_disown();\n",
  1486. "}\n",
  1487. NULL);
  1488. Setattr(disown, "wrap:action", action);
  1489. Setattr(disown,"name", mrename);
  1490. Setattr(disown,"sym:name", mrename);
  1491. Setattr(disown,"type",type);
  1492. Setattr(disown,"parms", p);
  1493. Delete(action);
  1494. Delete(mrename);
  1495. Delete(type);
  1496. Delete(p);
  1497. functionWrapper(disown);
  1498. Delete(disown);
  1499. return SWIG_OK;
  1500. }
  1501. /* ----------------------------------------------------------------------
  1502. * Language::classDirectorConstructors()
  1503. * ---------------------------------------------------------------------- */
  1504. int Language::classDirectorConstructors(Node *n) {
  1505. Node *ni;
  1506. String *nodeType;
  1507. Node *parent = Swig_methodclass(n);
  1508. int default_ctor = Getattr(parent,"allocate:default_constructor") ? 1 : 0;
  1509. int protected_ctor = 0;
  1510. int constructor = 0;
  1511. /* emit constructors */
  1512. for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
  1513. nodeType = Getattr(ni, "nodeType");
  1514. if (!Cmp(nodeType, "constructor")) {
  1515. Parm *parms = Getattr(ni,"parms");
  1516. if (is_public(ni)) {
  1517. /* emit public constructor */
  1518. classDirectorConstructor(ni);
  1519. constructor = 1;
  1520. if (default_ctor)
  1521. default_ctor = !ParmList_numrequired(parms);
  1522. } else {
  1523. /* emit protected constructor if needed */
  1524. if (need_nonpublic_ctor(ni)) {
  1525. classDirectorConstructor(ni);
  1526. constructor = 1;
  1527. protected_ctor = 1;
  1528. if (default_ctor)
  1529. default_ctor = !ParmList_numrequired(parms);
  1530. }
  1531. }
  1532. }
  1533. }
  1534. /* emit default constructor if needed */
  1535. if (!constructor) {
  1536. if (!default_ctor) {
  1537. /* we get here because the class has no public, protected or
  1538. default constructor, therefore, the director class can't be
  1539. created, ie, is kind of abstract. */
  1540. Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT,Getfile(n),Getline(n),
  1541. "Director class '%s' can't be constructed\n",
  1542. SwigType_namestr(Getattr(n,"name")));
  1543. return SWIG_OK;
  1544. }
  1545. classDirectorDefaultConstructor(n);
  1546. default_ctor = 1;
  1547. }
  1548. /* this is just to support old java behavior, ie, the default
  1549. constructor is always emitted, even when protected, and not
  1550. needed, since there is a public constructor already defined.
  1551. (scottm) This code is needed here to make the director_abstract +
  1552. test generate compileable code (Example2 in director_abastract.i).
  1553. (mmatus) This is very strange, since swig compiled with gcc3.2.3
  1554. doesn't need it here....
  1555. */
  1556. if (!default_ctor && !protected_ctor) {
  1557. if (Getattr(parent,"allocate:default_base_constructor")) {
  1558. classDirectorDefaultConstructor(n);
  1559. }
  1560. }
  1561. return SWIG_OK;
  1562. }
  1563. /* ----------------------------------------------------------------------
  1564. * Language::classDirectorMethods()
  1565. * ---------------------------------------------------------------------- */
  1566. int Language::classDirectorMethods(Node *n) {
  1567. Node *vtable = Getattr(n, "vtable");
  1568. Node *item;
  1569. Iterator k;
  1570. for (k = First(vtable); k.key; k = Next(k)) {
  1571. item = k.item;
  1572. String *method = Getattr(item, "methodNode");
  1573. String *fqdname = Getattr(item, "fqdname");
  1574. if (GetFlag(method, "feature:nodirector"))
  1575. continue;
  1576. String *type = Getattr(method, "nodeType");
  1577. if (!Cmp(type, "destructor")) {
  1578. classDirectorDestructor(method);
  1579. } else {
  1580. if (classDirectorMethod(method, n, fqdname) == SWIG_OK) {
  1581. Setattr(item, "director", "1");
  1582. }
  1583. }
  1584. }
  1585. return SWIG_OK;
  1586. }
  1587. /* ----------------------------------------------------------------------
  1588. * Language::classDirectorInit()
  1589. * ---------------------------------------------------------------------- */
  1590. int Language::classDirectorInit(Node *n) {
  1591. (void)n;
  1592. return SWIG_OK;
  1593. }
  1594. /* ----------------------------------------------------------------------
  1595. * Language::classDirectorDestructor()
  1596. * ---------------------------------------------------------------------- */
  1597. int Language::classDirectorDestructor(Node *n) {
  1598. /*
  1599. Always emit the virtual destructor in the declaration and in the
  1600. compilation unit. Been explicit here can't make any damage, and
  1601. can solve some nasty C++ compiler problems.
  1602. */
  1603. File *f_directors = Swig_filebyname("director");
  1604. File *f_directors_h = Swig_filebyname("director_h");
  1605. String *classname= Swig_class_name(getCurrentClass());
  1606. if (Getattr(n,"throw")) {
  1607. Printf(f_directors_h, " virtual ~SwigDirector_%s() throw ();\n", classname);
  1608. Printf(f_directors, "SwigDirector_%s::~SwigDirector_%s() throw () {\n}\n\n", classname, classname);
  1609. } else {
  1610. Printf(f_directors_h, " virtual ~SwigDirector_%s();\n", classname);
  1611. Printf(f_directors, "SwigDirector_%s::~SwigDirector_%s() {\n}\n\n", classname, classname);
  1612. }
  1613. Delete(classname);
  1614. return SWIG_OK;
  1615. }
  1616. /* ----------------------------------------------------------------------
  1617. * Language::classDirectorEnd()
  1618. * ---------------------------------------------------------------------- */
  1619. int Language::classDirectorEnd(Node *n) {
  1620. (void)n;
  1621. return SWIG_OK;
  1622. }
  1623. /* ----------------------------------------------------------------------
  1624. * Language::classDirector()
  1625. * ---------------------------------------------------------------------- */
  1626. int Language::classDirector(Node *n) {
  1627. Node *module = Getattr(n,"module");
  1628. String *classtype = Getattr(n, "classtype");
  1629. Hash *directormap = 0;
  1630. if (module) {
  1631. directormap = Getattr(module, "wrap:directormap");
  1632. if (directormap == 0) {
  1633. directormap = NewHash();
  1634. Setattr(module, "wrap:directormap", directormap);
  1635. }
  1636. }
  1637. Hash* vtable = NewHash();
  1638. int virtual_destructor = 0;
  1639. unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
  1640. if (virtual_destructor || Len(vtable) > 0) {
  1641. if (!virtual_destructor) {
  1642. String *classtype = Getattr(n, "classtype");
  1643. Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number,
  1644. "Director base class %s has no virtual destructor.\n",
  1645. classtype);
  1646. }
  1647. Setattr(n, "vtable", vtable);
  1648. if (directormap != 0) {
  1649. Setattr(directormap, classtype, n);
  1650. }
  1651. classDirectorInit(n);
  1652. classDirectorConstructors(n);
  1653. classDirectorMethods(n);
  1654. classDirectorEnd(n);
  1655. }
  1656. Delete(vtable);
  1657. return SWIG_OK;
  1658. }
  1659. /* ----------------------------------------------------------------------
  1660. * Language::classDeclaration()
  1661. * ---------------------------------------------------------------------- */
  1662. int Language::classDeclaration(Node *n) {
  1663. String *ochildren = Getattr(n,"feature:onlychildren");
  1664. if (ochildren) {
  1665. Setattr(n,"feature:emitonlychildren",ochildren);
  1666. emit_children(n);
  1667. Delattr(n,"feature:emitonlychildren");
  1668. SetFlag(n,"feature:ignore");
  1669. return SWIG_NOWRAP;
  1670. }
  1671. String *kind = Getattr(n,"kind");
  1672. String *name = Getattr(n,"name");
  1673. String *tdname = Getattr(n,"tdname");
  1674. String *symname = Getattr(n,"sym:name");
  1675. char *classname = tdname ? Char(tdname) : Char(name);
  1676. char *iname = Char(symname);
  1677. int strip = (tdname || CPlusPlus) ? 1 : 0;
  1678. if (!classname) {
  1679. Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
  1680. return SWIG_NOWRAP;
  1681. }
  1682. /* Check symbol name for template. If not renamed. Issue a warning */
  1683. /* Printf(stdout,"sym:name = %s\n", symname); */
  1684. if (!validIdentifier(symname)) {
  1685. Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n",
  1686. SwigType_namestr(symname));
  1687. return SWIG_NOWRAP;
  1688. }
  1689. Swig_save("classDeclaration",n,"name",NIL);
  1690. Setattr(n,"name",classname);
  1691. if (Cmp(kind,"class") == 0) {
  1692. cplus_mode = PRIVATE;
  1693. } else {
  1694. cplus_mode = PUBLIC;
  1695. }
  1696. ClassName = NewString(classname);
  1697. ClassPrefix = NewString(iname);
  1698. if (strip) {
  1699. ClassType = NewString(classname);
  1700. } else {
  1701. ClassType = NewStringf("%s %s", kind, classname);
  1702. }
  1703. Setattr(n,"classtypeobj", Copy(ClassType));
  1704. Setattr(n,"classtype", SwigType_namestr(ClassType));
  1705. InClass = 1;
  1706. CurrentClass = n;
  1707. /* Call classHandler() here */
  1708. if (!ImportMode) {
  1709. int ndir = GetFlag(n, "feature:director");
  1710. int nndir = GetFlag(n, "feature:nodirector");
  1711. /* 'nodirector' has precedence over 'director' */
  1712. int dir = (ndir || nndir) ? (ndir && !nndir) : 0;
  1713. if (directorsEnabled() && dir) {
  1714. classDirector(n);
  1715. }
  1716. /* check for abstract after resolving directors */
  1717. Abstract = abstractClassTest(n);
  1718. classHandler(n);
  1719. } else {
  1720. Abstract = abstractClassTest(n);
  1721. Language::classHandler(n);
  1722. }
  1723. InClass = 0;
  1724. CurrentClass = 0;
  1725. Delete(ClassType); ClassType = 0;
  1726. Delete(ClassPrefix); ClassPrefix = 0;
  1727. Delete(ClassName); ClassName = 0;
  1728. Swig_restore(n);
  1729. return SWIG_OK;
  1730. }
  1731. /* ----------------------------------------------------------------------
  1732. * Language::classHandler()
  1733. * ---------------------------------------------------------------------- */
  1734. static Node *makeConstructor(Node *n)
  1735. {
  1736. Node *cn = Copy(n);
  1737. String *name = Getattr(n,"name");
  1738. String *rname = 0;
  1739. String *dname = NewStringf("%s::",name);
  1740. if (SwigType_istemplate(name)) {
  1741. rname = SwigType_templateprefix(name);
  1742. name = rname;
  1743. }
  1744. String *lname = Swig_scopename_last(name);
  1745. Append(dname,lname);
  1746. SetFlag(cn,"feature:new");
  1747. Setattr(cn,"decl","f().");
  1748. Swig_features_get(Swig_cparse_features(), 0, dname, Getattr(cn,"decl"), cn);
  1749. Delete(rname);
  1750. Delete(dname);
  1751. Delete(lname);
  1752. return cn;
  1753. }
  1754. static Node *makeDestructor(Node *n)
  1755. {
  1756. Node *cn = Copy(n);
  1757. String *name = Getattr(n,"name");
  1758. String *rname = 0;
  1759. String *dname = NewStringf("%s::~",name);
  1760. if (SwigType_istemplate(name)) {
  1761. rname = SwigType_templateprefix(name);
  1762. name = rname;
  1763. }
  1764. String *lname = Swig_scopename_last(name);
  1765. Append(dname,lname);
  1766. Setattr(cn,"decl","f().");
  1767. Swig_features_get(Swig_cparse_features(), 0, dname, Getattr(cn,"decl"), cn);
  1768. Delete(rname);
  1769. Delete(dname);
  1770. Delete(lname);
  1771. return cn;
  1772. }
  1773. int Language::classHandler(Node *n) {
  1774. bool hasDirector = Swig_directorclass(n) ? true : false;
  1775. /* Emit all of the class members */
  1776. emit_children(n);
  1777. /* Look for smart pointer handling */
  1778. if (Getattr(n,"allocate:smartpointer")) {
  1779. List *methods = Getattr(n,"allocate:smartpointer");
  1780. cplus_mode = PUBLIC;
  1781. SmartPointer = CWRAP_SMART_POINTER;
  1782. Iterator c;
  1783. for (c = First(methods); c.item; c= Next(c)) {
  1784. emit_one(c.item);
  1785. }
  1786. SmartPointer = 0;
  1787. }
  1788. cplus_mode = PUBLIC;
  1789. if (!ImportMode && (GenerateDefault && !GetFlag(n,"feature:nodefault"))) {
  1790. if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) {
  1791. /* Note: will need to change this to support different kinds of classes */
  1792. if (!Abstract) {
  1793. Node *cn = makeConstructor(CurrentClass);
  1794. constructorHandler(cn);
  1795. Delete(cn);
  1796. }
  1797. }
  1798. if (!Getattr(n,"has_destructor") && (!Getattr(n,"allocate:has_destructor")) && (Getattr(n,"allocate:default_destructor"))) {
  1799. Node *cn = makeDestructor(CurrentClass);
  1800. destructorHandler(cn);
  1801. Delete(cn);
  1802. }
  1803. }
  1804. /* emit director disown method */
  1805. if (hasDirector) {
  1806. classDirectorDisown(n);
  1807. /* emit all the protected virtual members as needed */
  1808. if (dirprot_mode()) {
  1809. Node *vtable = Getattr(n, "vtable");
  1810. String* symname = Getattr(n, "sym:name");
  1811. Node *item;
  1812. Iterator k;
  1813. AccessMode old_mode = cplus_mode;
  1814. cplus_mode = PROTECTED;
  1815. for (k = First(vtable); k.key; k = Next(k)) {
  1816. item = k.item;
  1817. Node *method = Getattr(item, "methodNode");
  1818. SwigType *type = Getattr(method,"nodeType");
  1819. if (Strcmp(type,"cdecl") !=0 ) continue;
  1820. String* methodname = Getattr(method,"sym:name");
  1821. String* wrapname = NewStringf("%s_%s", symname,methodname);
  1822. if (!Getattr(symbols,wrapname)
  1823. && (!is_public(method))) {
  1824. Node* m = Copy(method);
  1825. Setattr(m, "director", "1");
  1826. Setattr(m,"parentNode", n);
  1827. cDeclaration(m);
  1828. Delete(m);
  1829. }
  1830. Delete(wrapname);
  1831. }
  1832. cplus_mode = old_mode;
  1833. }
  1834. }
  1835. return SWIG_OK;
  1836. }
  1837. /* ----------------------------------------------------------------------
  1838. * Language::classforwardDeclaration()
  1839. * ---------------------------------------------------------------------- */
  1840. int Language::classforwardDeclaration(Node *n) {
  1841. (void)n;
  1842. return SWIG_OK;
  1843. }
  1844. /* ----------------------------------------------------------------------
  1845. * Language::constructorDeclaration()
  1846. * ---------------------------------------------------------------------- */
  1847. int Language::constructorDeclaration(Node *n) {
  1848. String *name = Getattr(n,"name");
  1849. String *symname = Getattr(n,"sym:name");
  1850. if (!CurrentClass) return SWIG_NOWRAP;
  1851. if (ImportMode) return SWIG_NOWRAP;
  1852. /* clean protected overloaded constructors, in case they are not
  1853. needed anymore */
  1854. Node *over = Swig_symbol_isoverloaded(n);