PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1-3-24/SWIG/Source/Modules/csharp.cxx

#
C++ | 1776 lines | 1226 code | 293 blank | 257 comment | 298 complexity | aea27b8ea2204f0bf252365dcfba5a3f MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * csharp.cxx
  3. *
  4. * CSharp wrapper module.
  5. *
  6. * Author(s) : William Fulton
  7. * Neil Cawse
  8. *
  9. * Copyright (C) 1999-2002. The University of Chicago
  10. * See the file LICENSE for information on usage and redistribution.
  11. * ----------------------------------------------------------------------------- */
  12. char cvsroot_csharp_cxx[] = "$Header$";
  13. #include <limits.h> // for INT_MAX
  14. #include "swigmod.h"
  15. #include <ctype.h>
  16. class CSHARP : public Language {
  17. static const char *usage;
  18. const String *empty_string;
  19. const String *public_string;
  20. const String *protected_string;
  21. Hash *swig_types_hash;
  22. File *f_runtime;
  23. File *f_header;
  24. File *f_wrappers;
  25. File *f_init;
  26. bool proxy_flag; // Flag for generating proxy classes
  27. bool have_default_constructor_flag;
  28. bool native_function_flag; // Flag for when wrapping a native function
  29. bool enum_constant_flag; // Flag for when wrapping an enum or constant
  30. bool static_flag; // Flag for when wrapping a static functions or member variables
  31. bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable
  32. bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const
  33. bool global_variable_flag; // Flag for when wrapping a global variable
  34. String *imclass_name; // intermediary class name
  35. String *module_class_name; // module class name
  36. String *imclass_class_code; // intermediary class code
  37. String *proxy_class_def;
  38. String *proxy_class_code;
  39. String *module_class_code;
  40. String *proxy_class_name;
  41. String *variable_name; //Name of a variable being wrapped
  42. String *proxy_class_constants_code;
  43. String *module_class_constants_code;
  44. String *enum_code;
  45. String *dllimport; // DllImport attribute name
  46. String *namespce; // Optional namespace name
  47. String *imclass_imports; //intermediary class imports from %pragma
  48. String *module_imports; //module imports from %pragma
  49. String *imclass_baseclass; //inheritance for intermediary class class from %pragma
  50. String *module_baseclass; //inheritance for module class from %pragma
  51. String *imclass_interfaces; //interfaces for intermediary class class from %pragma
  52. String *module_interfaces; //interfaces for module class from %pragma
  53. String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
  54. String *module_class_modifiers; //class modifiers for module class overriden by %pragma
  55. String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
  56. String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
  57. String *destructor_call; //C++ destructor call if any
  58. enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
  59. public:
  60. /* -----------------------------------------------------------------------------
  61. * CSHARP()
  62. * ----------------------------------------------------------------------------- */
  63. CSHARP() :
  64. empty_string(NewString("")),
  65. public_string(NewString("public")),
  66. protected_string(NewString("protected")),
  67. swig_types_hash(NULL),
  68. f_runtime(NULL),
  69. f_header(NULL),
  70. f_wrappers(NULL),
  71. f_init(NULL),
  72. proxy_flag(true),
  73. have_default_constructor_flag(false),
  74. native_function_flag(false),
  75. enum_constant_flag(false),
  76. static_flag(false),
  77. variable_wrapper_flag(false),
  78. wrapping_member_flag(false),
  79. global_variable_flag(false),
  80. imclass_name(NULL),
  81. module_class_name(NULL),
  82. imclass_class_code(NULL),
  83. proxy_class_def(NULL),
  84. proxy_class_code(NULL),
  85. module_class_code(NULL),
  86. proxy_class_name(NULL),
  87. variable_name(NULL),
  88. proxy_class_constants_code(NULL),
  89. module_class_constants_code(NULL),
  90. enum_code(NULL),
  91. dllimport(NULL),
  92. namespce(NULL),
  93. imclass_imports(NULL),
  94. module_imports(NULL),
  95. imclass_baseclass(NULL),
  96. module_baseclass(NULL),
  97. imclass_interfaces(NULL),
  98. module_interfaces(NULL),
  99. imclass_class_modifiers(NULL),
  100. module_class_modifiers(NULL),
  101. upcasts_code(NULL),
  102. imclass_cppcasts_code(NULL),
  103. destructor_call(NULL)
  104. {
  105. }
  106. /* -----------------------------------------------------------------------------
  107. * getProxyName()
  108. *
  109. * Test to see if a type corresponds to something wrapped with a proxy class
  110. * Return NULL if not otherwise the proxy class name
  111. * ----------------------------------------------------------------------------- */
  112. String *getProxyName(SwigType *t) {
  113. if (proxy_flag) {
  114. Node *n = classLookup(t);
  115. if (n) {
  116. return Getattr(n,"sym:name");
  117. }
  118. }
  119. return NULL;
  120. }
  121. /* ------------------------------------------------------------
  122. * main()
  123. * ------------------------------------------------------------ */
  124. virtual void main(int argc, char *argv[]) {
  125. SWIG_library_directory("csharp");
  126. // Look for certain command line options
  127. for (int i = 1; i < argc; i++) {
  128. if (argv[i]) {
  129. if (strcmp(argv[i],"-dllimport") == 0) {
  130. if (argv[i+1]) {
  131. dllimport = NewString("");
  132. Printf(dllimport, argv[i+1]);
  133. Swig_mark_arg(i);
  134. Swig_mark_arg(i+1);
  135. i++;
  136. } else {
  137. Swig_arg_error();
  138. }
  139. } else if (strcmp(argv[i],"-namespace") == 0) {
  140. if (argv[i+1]) {
  141. namespce = NewString("");
  142. Printf(namespce, argv[i+1]);
  143. Swig_mark_arg(i);
  144. Swig_mark_arg(i+1);
  145. i++;
  146. } else {
  147. Swig_arg_error();
  148. }
  149. } else if ((strcmp(argv[i],"-noproxy") == 0)) {
  150. Swig_mark_arg(i);
  151. proxy_flag = false;
  152. } else if (strcmp(argv[i],"-help") == 0) {
  153. Printf(stderr,"%s\n", usage);
  154. }
  155. }
  156. }
  157. // Add a symbol to the parser for conditional compilation
  158. Preprocessor_define("SWIGCSHARP 1",0);
  159. // Add typemap definitions
  160. SWIG_typemap_lang("csharp");
  161. SWIG_config_file("csharp.swg");
  162. allow_overloading();
  163. }
  164. /* ---------------------------------------------------------------------
  165. * top()
  166. * --------------------------------------------------------------------- */
  167. virtual int top(Node *n) {
  168. // Get any options set in the module directive
  169. Node* optionsnode = Getattr( Getattr(n,"module"), "options");
  170. if (optionsnode) {
  171. if (Getattr(optionsnode,"imclassname"))
  172. imclass_name = Copy(Getattr(optionsnode,"imclassname"));
  173. }
  174. /* Initialize all of the output files */
  175. String *outfile = Getattr(n,"outfile");
  176. f_runtime = NewFile(outfile,"w");
  177. if (!f_runtime) {
  178. Printf(stderr,"Unable to open %s\n", outfile);
  179. SWIG_exit(EXIT_FAILURE);
  180. }
  181. f_init = NewString("");
  182. f_header = NewString("");
  183. f_wrappers = NewString("");
  184. /* Register file targets with the SWIG file handler */
  185. Swig_register_filebyname("header",f_header);
  186. Swig_register_filebyname("wrapper",f_wrappers);
  187. Swig_register_filebyname("runtime",f_runtime);
  188. Swig_register_filebyname("init",f_init);
  189. swig_types_hash = NewHash();
  190. // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
  191. if (!imclass_name) {
  192. imclass_name = NewStringf("%sPINVOKE", Getattr(n,"name"));
  193. module_class_name = Copy(Getattr(n,"name"));
  194. } else {
  195. // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
  196. if (Cmp(imclass_name, Getattr(n,"name")) == 0)
  197. module_class_name = NewStringf("%sModule", Getattr(n,"name"));
  198. else
  199. module_class_name = Copy(Getattr(n,"name"));
  200. }
  201. imclass_class_code = NewString("");
  202. proxy_class_def = NewString("");
  203. proxy_class_code = NewString("");
  204. module_class_constants_code = NewString("");
  205. imclass_baseclass = NewString("");
  206. imclass_interfaces = NewString("");
  207. imclass_class_modifiers = NewString("");
  208. module_class_code = NewString("");
  209. module_baseclass = NewString("");
  210. module_interfaces = NewString("");
  211. module_imports = NewString("");
  212. module_class_modifiers = NewString("");
  213. imclass_imports = NewString("");
  214. imclass_cppcasts_code = NewString("");
  215. upcasts_code = NewString("");
  216. if (!namespce) namespce = NewString("");
  217. if (!dllimport) dllimport = Copy(module_class_name);
  218. Swig_banner(f_runtime); // Print the SWIG banner message
  219. String *wrapper_name = NewString("");
  220. Printf(wrapper_name, "CSharp_%%f", imclass_name);
  221. Swig_name_register((char*)"wrapper", Char(wrapper_name));
  222. Swig_name_register((char*)"set", (char*)"set_%v");
  223. Swig_name_register((char*)"get", (char*)"get_%v");
  224. Swig_name_register((char*)"member", (char*)"%c_%m");
  225. Delete(wrapper_name);
  226. Printf(f_wrappers,"\n#ifdef __cplusplus\n");
  227. Printf(f_wrappers,"extern \"C\" {\n");
  228. Printf(f_wrappers,"#endif\n\n");
  229. /* Emit code */
  230. Language::top(n);
  231. // Generate the intermediary class
  232. {
  233. String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), imclass_name);
  234. File *f_im = NewFile(filen,"w");
  235. if(!f_im) {
  236. Printf(stderr,"Unable to open %s\n", filen);
  237. SWIG_exit(EXIT_FAILURE);
  238. }
  239. Delete(filen); filen = NULL;
  240. // Start writing out the intermediary class file
  241. emitBanner(f_im);
  242. if(Len(namespce) > 0)
  243. Printf(f_im, "namespace %s {\n", namespce);
  244. if(imclass_imports)
  245. Printf(f_im, "%s\n", imclass_imports);
  246. if (Len(imclass_class_modifiers) > 0)
  247. Printf(f_im, "%s ", imclass_class_modifiers);
  248. Printf(f_im, "%s ", imclass_name);
  249. if (imclass_baseclass && *Char(imclass_baseclass))
  250. Printf(f_im, ": %s ", imclass_baseclass);
  251. if (Len(imclass_interfaces) > 0)
  252. Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
  253. Printf(f_im, "{\n");
  254. // Add the intermediary class methods
  255. Replaceall(imclass_class_code, "$module", module_class_name);
  256. Replaceall(imclass_class_code, "$dllimport", dllimport);
  257. Printv(f_im, imclass_class_code, NIL);
  258. Printv(f_im, imclass_cppcasts_code, NIL);
  259. // Finish off the class
  260. Printf(f_im, "}\n");
  261. Printf(f_im, Len(namespce) > 0 ? "\n}\n" : "");
  262. Close(f_im);
  263. }
  264. // Generate the C# module class
  265. {
  266. String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), module_class_name);
  267. File *f_module = NewFile(filen,"w");
  268. if(!f_module) {
  269. Printf(stderr,"Unable to open %s\n", filen);
  270. SWIG_exit(EXIT_FAILURE);
  271. }
  272. Delete(filen); filen = NULL;
  273. // Start writing out the module class file
  274. emitBanner(f_module);
  275. if(Len(namespce) > 0)
  276. Printf(f_module, "namespace %s {\n", namespce);
  277. if(module_imports)
  278. Printf(f_module, "%s\n", module_imports);
  279. if (Len(module_class_modifiers) > 0)
  280. Printf(f_module, "%s ", module_class_modifiers);
  281. Printf(f_module, "%s ", module_class_name);
  282. if (module_baseclass && *Char(module_baseclass))
  283. Printf(f_module, ": %s ", module_baseclass);
  284. if (Len(module_interfaces) > 0)
  285. Printv(f_module, "implements ", module_interfaces, " ", NIL);
  286. Printf(f_module, "{\n");
  287. Replaceall(module_class_code, "$module", module_class_name);
  288. Replaceall(module_class_constants_code, "$module", module_class_name);
  289. Replaceall(module_class_code, "$dllimport", dllimport);
  290. Replaceall(module_class_constants_code, "$dllimport", dllimport);
  291. // Add the wrapper methods
  292. Printv(f_module, module_class_code, NIL);
  293. // Write out all the global constants
  294. Printv(f_module, module_class_constants_code, NIL);
  295. // Finish off the class
  296. Printf(f_module, "}\n");
  297. Printf(f_module, Len(namespce) > 0 ? "\n}\n" : "");
  298. Close(f_module);
  299. }
  300. if(upcasts_code)
  301. Printv(f_wrappers,upcasts_code,NIL);
  302. Printf(f_wrappers,"#ifdef __cplusplus\n");
  303. Printf(f_wrappers,"}\n");
  304. Printf(f_wrappers,"#endif\n");
  305. // Output a C# type wrapper class for each SWIG type
  306. for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
  307. emitTypeWrapperClass(swig_type.key, swig_type.item);
  308. }
  309. Delete(swig_types_hash); swig_types_hash = NULL;
  310. Delete(imclass_name); imclass_name = NULL;
  311. Delete(imclass_class_code); imclass_class_code = NULL;
  312. Delete(proxy_class_def); proxy_class_def = NULL;
  313. Delete(proxy_class_code); proxy_class_code = NULL;
  314. Delete(module_class_constants_code); module_class_constants_code = NULL;
  315. Delete(imclass_baseclass); imclass_baseclass = NULL;
  316. Delete(imclass_interfaces); imclass_interfaces = NULL;
  317. Delete(imclass_class_modifiers); imclass_class_modifiers = NULL;
  318. Delete(module_class_name); module_class_name = NULL;
  319. Delete(module_class_code); module_class_code = NULL;
  320. Delete(module_baseclass); module_baseclass = NULL;
  321. Delete(module_interfaces); module_interfaces = NULL;
  322. Delete(module_imports); module_imports = NULL;
  323. Delete(module_class_modifiers); module_class_modifiers = NULL;
  324. Delete(imclass_imports); imclass_imports = NULL;
  325. Delete(imclass_cppcasts_code); imclass_cppcasts_code = NULL;
  326. Delete(upcasts_code); upcasts_code = NULL;
  327. Delete(namespce); namespce = NULL;
  328. /* Close all of the files */
  329. Dump(f_header,f_runtime);
  330. Dump(f_wrappers,f_runtime);
  331. Wrapper_pretty_print(f_init,f_runtime);
  332. Delete(f_header);
  333. Delete(f_wrappers);
  334. Delete(f_init);
  335. Close(f_runtime);
  336. Delete(f_runtime);
  337. return SWIG_OK;
  338. }
  339. /* -----------------------------------------------------------------------------
  340. * emitBanner()
  341. * ----------------------------------------------------------------------------- */
  342. void emitBanner(File *f) {
  343. Printf(f, "/* ----------------------------------------------------------------------------\n");
  344. Printf(f, " * This file was automatically generated by SWIG (http://www.swig.org).\n");
  345. Printf(f, " * Version %s\n", PACKAGE_VERSION);
  346. Printf(f, " *\n");
  347. Printf(f, " * Do not make changes to this file unless you know what you are doing--modify\n");
  348. Printf(f, " * the SWIG interface file instead.\n");
  349. Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
  350. }
  351. /* ----------------------------------------------------------------------
  352. * nativeWrapper()
  353. * ---------------------------------------------------------------------- */
  354. virtual int nativeWrapper(Node *n) {
  355. String *wrapname = Getattr(n,"wrap:name");
  356. if (!addSymbol(wrapname,n)) return SWIG_ERROR;
  357. if (Getattr(n,"type")) {
  358. Swig_save("nativeWrapper",n,"name",NIL);
  359. Setattr(n,"name", wrapname);
  360. native_function_flag = true;
  361. functionWrapper(n);
  362. Swig_restore(n);
  363. native_function_flag = false;
  364. } else {
  365. Printf(stderr,"%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n,"wrap:name"));
  366. }
  367. return SWIG_OK;
  368. }
  369. /* ----------------------------------------------------------------------
  370. * functionWrapper()
  371. * ---------------------------------------------------------------------- */
  372. virtual int functionWrapper(Node *n) {
  373. String *symname = Getattr(n,"sym:name");
  374. SwigType *t = Getattr(n,"type");
  375. ParmList *l = Getattr(n,"parms");
  376. String *tm;
  377. Parm *p;
  378. int i;
  379. String *c_return_type = NewString("");
  380. String *im_return_type = NewString("");
  381. String *cleanup = NewString("");
  382. String *outarg = NewString("");
  383. String *body = NewString("");
  384. int num_arguments = 0;
  385. int num_required = 0;
  386. bool is_void_return;
  387. String *overloaded_name = getOverloadedName(n);
  388. if (!Getattr(n,"sym:overloaded")) {
  389. if (!addSymbol(Getattr(n,"sym:name"),n)) return SWIG_ERROR;
  390. }
  391. /*
  392. * Generate the proxy class properties for public member variables.
  393. * Not for enums and constants.
  394. */
  395. if(proxy_flag && wrapping_member_flag && !enum_constant_flag) {
  396. // Capitalize the first letter in the variable in the getter/setter function name
  397. bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0;
  398. String *getter_setter_name = NewString("");
  399. if(!getter_flag)
  400. Printf(getter_setter_name,"set");
  401. else
  402. Printf(getter_setter_name,"get");
  403. Putc(toupper((int) *Char(variable_name)), getter_setter_name);
  404. Printf(getter_setter_name, "%s", Char(variable_name)+1);
  405. Setattr(n,"proxyfuncname", getter_setter_name);
  406. Setattr(n,"imfuncname", symname);
  407. proxyClassFunctionHandler(n);
  408. Delete(getter_setter_name);
  409. }
  410. /*
  411. The rest of this function deals with generating the intermediary class wrapper function (that wraps
  412. a c/c++ function) and generating the PInvoke c code. Each C# wrapper function has a
  413. matching PInvoke c function call.
  414. */
  415. // A new wrapper function object
  416. Wrapper *f = NewWrapper();
  417. // Make a wrapper name for this function
  418. String *wname = Swig_name_wrapper(overloaded_name);
  419. /* Attach the non-standard typemaps to the parameter list. */
  420. Swig_typemap_attach_parms("ctype", l, f);
  421. Swig_typemap_attach_parms("imtype", l, f);
  422. /* Get return types */
  423. if ((tm = Swig_typemap_lookup_new("ctype",n,"",0))) {
  424. Printf(c_return_type,"%s", tm);
  425. } else {
  426. Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number,
  427. "No ctype typemap defined for %s\n", SwigType_str(t,0));
  428. }
  429. if ((tm = Swig_typemap_lookup_new("imtype",n,"",0))) {
  430. Printf(im_return_type,"%s", tm);
  431. } else {
  432. Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number,
  433. "No imtype typemap defined for %s\n", SwigType_str(t,0));
  434. }
  435. is_void_return = (Cmp(c_return_type, "void") == 0);
  436. if (!is_void_return)
  437. Wrapper_add_localv(f,"jresult", c_return_type, "jresult = 0",NIL);
  438. Printv(f->def, " DllExport ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL);
  439. // Emit all of the local variables for holding arguments.
  440. emit_args(t,l,f);
  441. /* Attach the standard typemaps */
  442. emit_attach_parmmaps(l,f);
  443. // Parameter overloading
  444. Setattr(n,"wrap:parms",l);
  445. Setattr(n,"wrap:name", wname);
  446. // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
  447. if (Getattr(n,"sym:overloaded")) {
  448. // Emit warnings for the few cases that can't be overloaded in C# and give up on generating wrapper
  449. Swig_overload_check(n);
  450. if (Getattr(n, "overload:ignore"))
  451. return SWIG_OK;
  452. }
  453. Printv(imclass_class_code,
  454. "\n [DllImport(\"", dllimport, "\", EntryPoint=\"CSharp_", overloaded_name, "\")]\n", NIL);
  455. Printf(imclass_class_code, " public static extern %s %s(", im_return_type, overloaded_name);
  456. /* Get number of required and total arguments */
  457. num_arguments = emit_num_arguments(l);
  458. num_required = emit_num_required(l);
  459. int gencomma = 0;
  460. // Now walk the function parameter list and generate code to get arguments
  461. for (i = 0, p=l; i < num_arguments; i++) {
  462. while (checkAttribute(p,"tmap:in:numinputs","0")) {
  463. p = Getattr(p,"tmap:in:next");
  464. }
  465. SwigType *pt = Getattr(p,"type");
  466. String *ln = Getattr(p,"lname");
  467. String *im_param_type = NewString("");
  468. String *c_param_type = NewString("");
  469. String *arg = NewString("");
  470. Printf(arg,"j%s", ln);
  471. /* Get the ctype types of the parameter */
  472. if ((tm = Getattr(p,"tmap:ctype"))) {
  473. Printv(c_param_type, tm, NIL);
  474. } else {
  475. Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number,
  476. "No ctype typemap defined for %s\n", SwigType_str(pt,0));
  477. }
  478. /* Get the intermediary class parameter types of the parameter */
  479. if ((tm = Getattr(p,"tmap:imtype"))) {
  480. Printv(im_param_type, tm, NIL);
  481. } else {
  482. Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number,
  483. "No imtype typemap defined for %s\n", SwigType_str(pt,0));
  484. }
  485. /* Add parameter to intermediary class method */
  486. if(gencomma) Printf(imclass_class_code, ", ");
  487. Printf(imclass_class_code, "%s %s", im_param_type, arg);
  488. // Add parameter to C function
  489. Printv(f->def, gencomma?", ":"", c_param_type, " ", arg, NIL);
  490. gencomma = 1;
  491. // Get typemap for this argument
  492. if ((tm = Getattr(p,"tmap:in"))) {
  493. addThrows(n, "tmap:in", p);
  494. Replaceall(tm,"$source",arg); /* deprecated */
  495. Replaceall(tm,"$target",ln); /* deprecated */
  496. Replaceall(tm,"$arg",arg); /* deprecated? */
  497. Replaceall(tm,"$input", arg);
  498. Setattr(p,"emit:input", arg);
  499. Printf(f->code,"%s\n", tm);
  500. p = Getattr(p,"tmap:in:next");
  501. } else {
  502. Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
  503. "Unable to use type %s as a function argument.\n",SwigType_str(pt,0));
  504. p = nextSibling(p);
  505. }
  506. Delete(im_param_type);
  507. Delete(c_param_type);
  508. Delete(arg);
  509. }
  510. /* Insert constraint checking code */
  511. for (p = l; p;) {
  512. if ((tm = Getattr(p,"tmap:check"))) {
  513. addThrows(n, "tmap:check", p);
  514. Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */
  515. Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
  516. Replaceall(tm,"$input",Getattr(p,"emit:input"));
  517. Printv(f->code,tm,"\n",NIL);
  518. p = Getattr(p,"tmap:check:next");
  519. } else {
  520. p = nextSibling(p);
  521. }
  522. }
  523. /* Insert cleanup code */
  524. for (p = l; p;) {
  525. if ((tm = Getattr(p,"tmap:freearg"))) {
  526. addThrows(n, "tmap:freearg", p);
  527. Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */
  528. Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
  529. Replaceall(tm,"$input",Getattr(p,"emit:input"));
  530. Printv(cleanup,tm,"\n",NIL);
  531. p = Getattr(p,"tmap:freearg:next");
  532. } else {
  533. p = nextSibling(p);
  534. }
  535. }
  536. /* Insert argument output code */
  537. for (p = l; p;) {
  538. if ((tm = Getattr(p,"tmap:argout"))) {
  539. addThrows(n, "tmap:argout", p);
  540. Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */
  541. Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */
  542. Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
  543. Replaceall(tm,"$result","jresult");
  544. Replaceall(tm,"$input",Getattr(p,"emit:input"));
  545. Printv(outarg,tm,"\n",NIL);
  546. p = Getattr(p,"tmap:argout:next");
  547. } else {
  548. p = nextSibling(p);
  549. }
  550. }
  551. // Get any C# exception classes in the throws typemap
  552. ParmList *throw_parm_list = NULL;
  553. if ((throw_parm_list = Getattr(n,"throws"))) {
  554. Swig_typemap_attach_parms("throws", throw_parm_list, f);
  555. for (p = throw_parm_list; p; p=nextSibling(p)) {
  556. if ((tm = Getattr(p,"tmap:throws"))) {
  557. addThrows(n, "tmap:throws", p);
  558. }
  559. }
  560. }
  561. if (Cmp(nodeType(n), "constant") == 0) {
  562. // Wrapping a constant hack
  563. Swig_save("functionWrapper",n,"wrap:action",NIL);
  564. // below based on Swig_VargetToFunction()
  565. SwigType *ty = Swig_wrapped_var_type(Getattr(n,"type"));
  566. Setattr(n,"wrap:action", NewStringf("result = (%s) %s;\n", SwigType_lstr(ty,0), Getattr(n, "value")));
  567. }
  568. // Now write code to make the function call
  569. if(!native_function_flag)
  570. emit_action(n,f);
  571. if (Cmp(nodeType(n), "constant") == 0)
  572. Swig_restore(n);
  573. /* Return value if necessary */
  574. if(!native_function_flag) {
  575. if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
  576. addThrows(n, "tmap:out", n);
  577. Replaceall(tm,"$source", "result"); /* deprecated */
  578. Replaceall(tm,"$target", "jresult"); /* deprecated */
  579. Replaceall(tm,"$result","jresult");
  580. Printf(f->code,"%s", tm);
  581. if (Len(tm))
  582. Printf(f->code,"\n");
  583. } else {
  584. Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
  585. "Unable to use return type %s in function %s.\n", SwigType_str(t,0), Getattr(n,"name"));
  586. }
  587. }
  588. /* Output argument output code */
  589. Printv(f->code,outarg,NIL);
  590. /* Output cleanup code */
  591. Printv(f->code,cleanup,NIL);
  592. /* Look to see if there is any newfree cleanup code */
  593. if (Getattr(n,"feature:new")) {
  594. if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
  595. addThrows(n, "tmap:newfree", n);
  596. Replaceall(tm,"$source","result"); /* deprecated */
  597. Printf(f->code,"%s\n",tm);
  598. }
  599. }
  600. /* See if there is any return cleanup code */
  601. if(!native_function_flag) {
  602. if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
  603. Replaceall(tm,"$source","result"); /* deprecated */
  604. Printf(f->code,"%s\n",tm);
  605. }
  606. }
  607. /* Finish C function and intermediary class function definitions */
  608. Printf(imclass_class_code, ")");
  609. generateThrowsClause(n, imclass_class_code);
  610. Printf(imclass_class_code, ";\n");
  611. Printf(f->def,") {");
  612. if(!is_void_return)
  613. Printv(f->code, " return jresult;\n", NIL);
  614. Printf(f->code, "}\n");
  615. /* Substitute the cleanup code */
  616. Replaceall(f->code,"$cleanup",cleanup);
  617. /* Contract macro modification */
  618. Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ");
  619. if(!is_void_return)
  620. Replaceall(f->code,"$null","0");
  621. else
  622. Replaceall(f->code,"$null","");
  623. /* Dump the function out */
  624. if(!native_function_flag)
  625. Wrapper_print(f,f_wrappers);
  626. if(!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
  627. moduleClassFunctionHandler(n);
  628. }
  629. Delete(c_return_type);
  630. Delete(im_return_type);
  631. Delete(cleanup);
  632. Delete(outarg);
  633. Delete(body);
  634. Delete(overloaded_name);
  635. DelWrapper(f);
  636. return SWIG_OK;
  637. }
  638. /* -----------------------------------------------------------------------
  639. * variableWrapper()
  640. * ----------------------------------------------------------------------- */
  641. virtual int variableWrapper(Node *n) {
  642. Language::variableWrapper(n);
  643. return SWIG_OK;
  644. }
  645. /* -----------------------------------------------------------------------
  646. * globalvariableHandler()
  647. * ------------------------------------------------------------------------ */
  648. virtual int globalvariableHandler(Node *n) {
  649. SwigType *t = Getattr(n,"type");
  650. String *tm;
  651. // Get the variable type
  652. if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) {
  653. substituteClassname(t, tm);
  654. } else {
  655. Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number,
  656. "No cstype typemap defined for %s\n", SwigType_str(t,0));
  657. }
  658. // Output the property's field declaration and accessor methods
  659. Printf(module_class_code, " public static %s %s {", tm, Getattr(n, "sym:name"));
  660. variable_name = Getattr(n,"sym:name");
  661. global_variable_flag = true;
  662. int ret = Language::globalvariableHandler(n);
  663. global_variable_flag = false;
  664. Printf(module_class_code, "\n }\n\n");
  665. return ret;
  666. }
  667. /* ----------------------------------------------------------------------
  668. * enumDeclaration()
  669. *
  670. * C/C++ enums can be mapped in one of 4 ways, depending on the cs:enum feature specified:
  671. * 1) Simple enums - simple constant within the proxy class or module class
  672. * 2) Typeunsafe enums - simple constant in a C# class (class named after the c++ enum name)
  673. * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
  674. * 4) Proper enums - proper C# enum
  675. * Anonymous enums always default to 1)
  676. * ---------------------------------------------------------------------- */
  677. virtual int enumDeclaration(Node *n) {
  678. if (!ImportMode) {
  679. if (getCurrentClass() && (cplus_mode != PUBLIC)) return SWIG_NOWRAP;
  680. enum_code = NewString("");
  681. String *symname = Getattr(n,"sym:name");
  682. String *constants_code = (proxy_flag && is_wrapping_class()) ? proxy_class_constants_code : module_class_constants_code;
  683. EnumFeature enum_feature = decodeEnumFeature(n);
  684. String *typemap_lookup_type = Getattr(n,"name");
  685. if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
  686. // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
  687. // Pure C# baseclass and interfaces
  688. const String *pure_baseclass = typemapLookup("csbase", typemap_lookup_type, WARN_NONE);
  689. const String *pure_interfaces = typemapLookup("csinterfaces", typemap_lookup_type, WARN_NONE);
  690. // Emit the enum
  691. Printv(enum_code,
  692. typemapLookup("csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
  693. " ",
  694. symname,
  695. (*Char(pure_baseclass) || *Char(pure_interfaces)) ?
  696. " : " :
  697. "",
  698. pure_baseclass,
  699. ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
  700. ", " :
  701. "",
  702. pure_interfaces,
  703. " {\n",
  704. NIL);
  705. } else {
  706. // Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
  707. if (symname && !Getattr(n,"unnamedinstance"))
  708. Printf(constants_code, " // %s \n", symname);
  709. }
  710. // Emit each enum item
  711. Language::enumDeclaration(n);
  712. if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
  713. // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
  714. // Finish the enum declaration
  715. // Typemaps are used to generate the enum definition in a similar manner to proxy classes.
  716. Printv(enum_code,
  717. (enum_feature == ProperEnum) ?
  718. "\n" :
  719. typemapLookup("csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
  720. typemapLookup("cscode", typemap_lookup_type, WARN_NONE), // extra C# code
  721. "}\n",
  722. "\n",
  723. NIL);
  724. Replaceall(enum_code, "$csclassname", symname);
  725. // Substitute $enumvalues - intended usage is for typesafe enums
  726. if (Getattr(n,"enumvalues"))
  727. Replaceall(enum_code, "$enumvalues", Getattr(n,"enumvalues"));
  728. else
  729. Replaceall(enum_code, "$enumvalues", "");
  730. if (proxy_flag && is_wrapping_class()) {
  731. // Enums defined within the C++ class are defined within the proxy class
  732. // Add extra indentation
  733. Replaceall(enum_code, "\n ", "\n ");
  734. Replaceall(enum_code, "\n}\n", "\n }\n");
  735. Printv(proxy_class_constants_code, " ", enum_code, NIL);
  736. } else {
  737. // Global enums are defined in their own file
  738. String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), symname);
  739. File *f_enum = NewFile(filen,"w");
  740. if(!f_enum) {
  741. Printf(stderr,"Unable to open %s\n", filen);
  742. SWIG_exit(EXIT_FAILURE);
  743. }
  744. Delete(filen); filen = NULL;
  745. // Start writing out the enum file
  746. emitBanner(f_enum);
  747. if(Len(namespce) > 0)
  748. Printf(f_enum, "namespace %s {\n", namespce);
  749. Printv(f_enum,
  750. typemapLookup("csimports", typemap_lookup_type, WARN_NONE), // Import statements
  751. "\n",
  752. enum_code,
  753. NIL);
  754. Printf(f_enum, Len(namespce) > 0 ? "\n}\n" : "\n");
  755. Close(f_enum);
  756. }
  757. } else {
  758. // Wrap C++ enum with simple constant
  759. Printf(enum_code, "\n");
  760. if (proxy_flag && is_wrapping_class())
  761. Printv(proxy_class_constants_code, enum_code, NIL);
  762. else
  763. Printv(module_class_constants_code, enum_code, NIL);
  764. }
  765. Delete(enum_code); enum_code = NULL;
  766. }
  767. return SWIG_OK;
  768. }
  769. /* ----------------------------------------------------------------------
  770. * enumvalueDeclaration()
  771. * ---------------------------------------------------------------------- */
  772. virtual int enumvalueDeclaration(Node *n) {
  773. if (getCurrentClass() && (cplus_mode != PUBLIC)) return SWIG_NOWRAP;
  774. Swig_require("enumvalueDeclaration",n,"*name", "?value",NIL);
  775. String *symname = Getattr(n,"sym:name");
  776. String *value = Getattr(n,"value");
  777. String *name = Getattr(n,"name");
  778. String *tmpValue;
  779. // Strange hack from parent method
  780. if (value)
  781. tmpValue = NewString(value);
  782. else
  783. tmpValue = NewString(name);
  784. // Note that this is used in enumValue() amongst other places
  785. Setattr(n, "value", tmpValue);
  786. {
  787. EnumFeature enum_feature = decodeEnumFeature(parentNode(n));
  788. if ((enum_feature == ProperEnum) && Getattr(parentNode(n),"sym:name") && !Getattr(parentNode(n),"unnamedinstance")) {
  789. // Wrap (non-anonymous) C/C++ enum with a proper C# enum
  790. // Emit the enum item.
  791. if (!Getattr(n,"_last")) // Only the first enum item has this attribute set
  792. Printf(enum_code, ",\n");
  793. Printf(enum_code, " %s", symname);
  794. // Check for the %csconstvalue feature
  795. String *value = Getattr(n,"feature:cs:constvalue");
  796. // Note that the enum value must be a true constant and cannot be set from a PINVOKE call, thus no support for %csconst(0)
  797. value = value ? value : Getattr(n,"enumvalue");
  798. if (value) {
  799. Printf(enum_code, " = %s", value);
  800. }
  801. } else {
  802. // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
  803. const String *parent_name = Getattr(parentNode(n),"name");
  804. String *typemap_lookup_type = parent_name ? Copy(parent_name) : NewString("int");
  805. const String *tm = typemapLookup("cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF);
  806. String *return_type = Copy(tm);
  807. Delete(typemap_lookup_type); typemap_lookup_type = NULL;
  808. // The %csconst feature determines how the constant value is obtained
  809. String *const_feature = Getattr(n,"feature:cs:const");
  810. bool const_feature_flag = const_feature && Cmp(const_feature, "0") != 0;
  811. if ((enum_feature == TypesafeEnum) && Getattr(parentNode(n),"sym:name") && !Getattr(parentNode(n),"unnamedinstance")) {
  812. // Wrap (non-anonymouse) enum using the typesafe enum pattern
  813. if (Getattr(n,"enumvalue")) {
  814. String *value = enumValue(n);
  815. Printf(enum_code, " public static readonly %s %s = new %s(\"%s\", %s);\n", return_type, symname, return_type, symname, value);
  816. Delete(value);
  817. } else {
  818. Printf(enum_code, " public static readonly %s %s = new %s(\"%s\");\n", return_type, symname, return_type, symname);
  819. }
  820. } else {
  821. // Simple integer constants
  822. // Note these are always generated for anonymous enums, no matter what enum_feature is specified
  823. // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
  824. const char *const_readonly = const_feature_flag ? "const" : "static readonly";
  825. String *value = enumValue(n);
  826. Printf(enum_code, " public %s %s %s = %s;\n", const_readonly, return_type, symname, value);
  827. Delete(value);
  828. }
  829. }
  830. // Add the enum value to the comma separated list being constructed in the enum declaration.
  831. String *enumvalues = Getattr(parentNode(n), "enumvalues");
  832. if (!enumvalues)
  833. Setattr(parentNode(n), "enumvalues", Copy(symname));
  834. else
  835. Printv(enumvalues, ", ", symname, NIL);
  836. }
  837. Delete(tmpValue);
  838. Swig_restore(n);
  839. return SWIG_OK;
  840. }
  841. /* -----------------------------------------------------------------------
  842. * constantWrapper()
  843. * Used for wrapping constants - #define or %constant.
  844. * Also for inline initialised const static primitive type member variables (short, int, double, enums etc).
  845. * C# static const variables are generated for these.
  846. * If the %csconst(1) feature is used then the C constant value is used to initialise the C# const variable.
  847. * If not, a PINVOKE method is generated to get the C constant value for initialisation of the C# const variable.
  848. * However, if the %csconstvalue feature is used, it overrides all other ways to generate the initialisation.
  849. * Also note that this method might be called for wrapping enum items (when the enum is using %csconst(0)).
  850. * ------------------------------------------------------------------------ */
  851. virtual int constantWrapper(Node *n) {
  852. String *symname = Getattr(n,"sym:name");
  853. SwigType *t = Getattr(n,"type");
  854. ParmList *l = Getattr(n,"parms");
  855. String *tm;
  856. String *return_type = NewString("");
  857. String *constants_code = NewString("");
  858. if (!addSymbol(symname,n)) return SWIG_ERROR;
  859. bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
  860. // The %csconst feature determines how the constant value is obtained
  861. String *const_feature = Getattr(n,"feature:cs:const");
  862. bool const_feature_flag = const_feature && Cmp(const_feature, "0") != 0;
  863. /* Adjust the enum type for the Swig_typemap_lookup.
  864. * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */
  865. if (is_enum_item) {
  866. t = Getattr(parentNode(n),"enumtype");
  867. Setattr(n,"type", t);
  868. }
  869. /* Attach the non-standard typemaps to the parameter list. */
  870. Swig_typemap_attach_parms("cstype", l, NULL);
  871. /* Get C# return types */
  872. bool classname_substituted_flag = false;
  873. if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) {
  874. classname_substituted_flag = substituteClassname(t, tm);
  875. Printf(return_type, "%s", tm);
  876. } else {
  877. Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number,
  878. "No cstype typemap defined for %s\n", SwigType_str(t,0));
  879. }
  880. // Add the stripped quotes back in
  881. String *new_value = NewString("");
  882. Swig_save("constantWrapper",n,"value",NIL);
  883. if(SwigType_type(t) == T_STRING) {
  884. Printf(new_value, "\"%s\"", Copy(Getattr(n, "value")));
  885. Setattr(n, "value", new_value);
  886. }
  887. else if(SwigType_type(t) == T_CHAR) {
  888. Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
  889. Setattr(n, "value", new_value);
  890. }
  891. const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
  892. Printf(constants_code, " public %s %s %s = ", (const_feature_flag ? "const" : "static readonly"), return_type, itemname);
  893. // Check for the %csconstvalue feature
  894. String *value = Getattr(n,"feature:cs:constvalue");
  895. if (value) {
  896. Printf(constants_code, "%s;\n", value);
  897. } else if (!const_feature_flag) {
  898. // Default enum and constant handling will work with any type of C constant and initialises the C# variable from C through a PINVOKE call.
  899. if(classname_substituted_flag) {
  900. if (SwigType_isenum(t)) {
  901. // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
  902. Printf(constants_code, "(%s)%s.%s();\n", return_type, imclass_name, Swig_name_get(symname));
  903. } else {
  904. // This handles function pointers using the %constant directive
  905. Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, imclass_name, Swig_name_get(symname));
  906. }
  907. } else
  908. Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(symname));
  909. // Each constant and enum value is wrapped with a separate PInvoke function call
  910. enum_constant_flag = true;
  911. variableWrapper(n);
  912. enum_constant_flag = false;
  913. } else {
  914. // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
  915. Printf(constants_code, "%s;\n", Getattr(n,"value"));
  916. }
  917. // Emit the generated code to appropriate place
  918. // Enums only emit the intermediate and PINVOKE methods, so no proxy or module class wrapper methods needed
  919. if (!is_enum_item) {
  920. if(proxy_flag && wrapping_member_flag)
  921. Printv(proxy_class_constants_code, constants_code, NIL);
  922. else
  923. Printv(module_class_constants_code, constants_code, NIL);
  924. }
  925. // Cleanup
  926. Swig_restore(n);
  927. Delete(new_value);
  928. Delete(return_type);
  929. Delete(constants_code);
  930. return SWIG_OK;
  931. }
  932. /* -----------------------------------------------------------------------------
  933. * insertDirective()
  934. * ----------------------------------------------------------------------------- */
  935. virtual int insertDirective(Node *n) {
  936. String *code = Getattr(n,"code");
  937. Replaceall(code, "$module", module_class_name);
  938. Replaceall(code, "$dllimport", dllimport);
  939. return Language::insertDirective(n);
  940. }
  941. /* -----------------------------------------------------------------------------
  942. * pragmaDirective()
  943. *
  944. * Valid Pragmas:
  945. * imclassbase - base (extends) for the intermediary class
  946. * imclassclassmodifiers - class modifiers for the intermediary class
  947. * imclasscode - text (C# code) is copied verbatim to the intermediary class
  948. * imclassimports - import statements for the intermediary class
  949. * imclassinterfaces - interface (implements) for the intermediary class
  950. *
  951. * modulebase - base (extends) for the module class
  952. * moduleclassmodifiers - class modifiers for the module class
  953. * modulecode - text (C# code) is copied verbatim to the module class
  954. * moduleimports - import statements for the module class
  955. * moduleinterfaces - interface (implements) for the module class
  956. *
  957. * ----------------------------------------------------------------------------- */
  958. virtual int pragmaDirective(Node *n) {
  959. if (!ImportMode) {
  960. String *lang = Getattr(n,"lang");
  961. String *code = Getattr(n,"name");
  962. String *value = Getattr(n,"value");
  963. if(Strcmp(lang, "csharp") == 0) {
  964. String *strvalue = NewString(value);
  965. Replaceall(strvalue,"\\\"", "\"");
  966. if(Strcmp(code, "imclassbase") == 0) {
  967. Delete(imclass_baseclass);
  968. imclass_baseclass = Copy(strvalue);
  969. }
  970. else if(Strcmp(code, "imclassclassmodifiers") == 0) {
  971. Delete(imclass_class_modifiers);
  972. imclass_class_modifiers = Copy(strvalue);
  973. }
  974. else if(Strcmp(code, "imclasscode") == 0) {
  975. Printf(imclass_class_code, "%s\n", strvalue);
  976. }
  977. else if(Strcmp(code, "imclassimports") == 0) {
  978. Delete(imclass_imports);
  979. imclass_imports = Copy(strvalue);
  980. }
  981. else if(Strcmp(code, "imclassinterfaces") == 0) {
  982. Delete(imclass_interfaces);
  983. imclass_interfaces = Copy(strvalue);
  984. }
  985. else if(Strcmp(code, "modulebase") == 0) {
  986. Delete(module_baseclass);
  987. module_baseclass = Copy(strvalue);
  988. }
  989. else if(Strcmp(code, "moduleclassmodifiers") == 0) {
  990. Delete(module_class_modifiers);
  991. module_class_modifiers = Copy(strvalue);
  992. }
  993. else if(Strcmp(code, "modulecode") == 0) {
  994. Printf(module_class_code, "%s\n", strvalue);
  995. }
  996. else if(Strcmp(code, "moduleimports") == 0) {
  997. Delete(module_imports);
  998. module_imports = Copy(strvalue);
  999. }
  1000. else if(Strcmp(code, "moduleinterfaces") == 0) {
  1001. Delete(module_interfaces);
  1002. module_interfaces = Copy(strvalue);
  1003. } else {
  1004. Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number);
  1005. }
  1006. Delete(strvalue);
  1007. }
  1008. }
  1009. return Language::pragmaDirective(n);
  1010. }
  1011. /* -----------------------------------------------------------------------------
  1012. * emitProxyClassDefAndCPPCasts()
  1013. * ----------------------------------------------------------------------------- */
  1014. void emitProxyClassDefAndCPPCasts(Node *n) {
  1015. String *c_classname = SwigType_namestr(Getattr(n,"name"));
  1016. String *c_baseclass = NULL;
  1017. String *baseclass = NULL;
  1018. String *c_baseclassname = NULL;
  1019. String *typemap_lookup_type = Getattr(n,"classtypeobj");
  1020. /* Deal with inheritance */
  1021. List *baselist = Getattr(n,"bases");
  1022. if (baselist) {
  1023. Iterator base = First(baselist);
  1024. c_baseclassname = Getattr(base.item,"name");
  1025. baseclass = Copy(getProxyName(c_baseclassname));
  1026. if (baseclass){
  1027. c_baseclass = SwigType_namestr(Getattr(base.item,"name"));
  1028. }
  1029. base = Next(base);
  1030. if (base.item) {
  1031. Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number,
  1032. "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", typemap_lookup_type, Getattr(base.item,"name"));
  1033. }
  1034. }
  1035. bool derived = baseclass && getProxyName(c_baseclassname);
  1036. if (!baseclass)
  1037. baseclass = NewString("");
  1038. // Inheritance from pure C# classes
  1039. const String *pure_baseclass = typemapLookup("csbase", typemap_lookup_type, WARN_NONE);
  1040. if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
  1041. Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number,
  1042. "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", typemap_lookup_type, pure_baseclass);
  1043. pure_baseclass = empty_string;
  1044. }
  1045. // Pure C# interfaces
  1046. const String *pure_interfaces = typemapLookup(derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
  1047. // Start writing the proxy class
  1048. Printv(proxy_class_def,
  1049. typemapLookup("csimports", typemap_lookup_type, WARN_NONE), // Import statements
  1050. "\n",
  1051. typemapLookup("csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
  1052. " $csclassname", // Class name and base class
  1053. (derived || *Char(pure_baseclass) || *Char(pure_interfaces)) ?
  1054. " : " :
  1055. "",
  1056. baseclass, // Note only one of these base classes should ever be set as multiple inheritance is not permissible
  1057. pure_baseclass,
  1058. ((derived || *Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
  1059. ", " :
  1060. "",
  1061. pure_interfaces,
  1062. " {",
  1063. derived ?
  1064. typemapLookup("csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class
  1065. typemapLookup("csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
  1066. NIL);
  1067. if(!have_default_constructor_flag) { // All proxy classes need a constructor
  1068. Printv(proxy_class_def,
  1069. "\n",
  1070. " protected $csclassname() : this(IntPtr.Zero, false) {\n",
  1071. " }\n",
  1072. NIL);
  1073. }
  1074. // C++ destructor is wrapped by the Dispose method
  1075. // Note that the method name is specified in a typemap attribute called methodname
  1076. String *destruct = NewString("");
  1077. const String *tm = NULL;
  1078. Node *attributes = NewHash();
  1079. String *destruct_methodname = NULL;
  1080. if (derived) {
  1081. tm = typemapLookup("csdestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
  1082. destruct_methodname = Getattr(attributes, "tmap:csdestruct_derived:methodname");
  1083. } else {
  1084. tm = typemapLookup("csdestruct", typemap_lookup_type, WARN_NONE, attributes);
  1085. destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname");
  1086. }
  1087. if (!destruct_methodname) {
  1088. Swig_error(input_file, line_number,
  1089. "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
  1090. }
  1091. // Emit the Finalize and Dispose methods
  1092. if (tm) {
  1093. // Finalize method
  1094. if (*Char(destructor_call)) {
  1095. Printv(proxy_class_def,
  1096. typemapLookup("csfinalize", typemap_lookup_type, WARN_NONE),
  1097. NIL);
  1098. }
  1099. // Dispose method
  1100. Printv(destruct, tm, NIL);
  1101. if (*Char(destructor_call))
  1102. Replaceall(destruct, "$imcall", destructor_call);
  1103. else
  1104. Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")");
  1105. if (*Char(destruct))
  1106. Printv(proxy_class_def, "\n public ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n", NIL);
  1107. }
  1108. Delete(attributes);
  1109. Delete(destruct);
  1110. // Emit extra user code
  1111. Printv(proxy_class_def,
  1112. typemapLookup("cscode", typemap_lookup_type, WARN_NONE), // extra C# code
  1113. "\n",
  1114. NIL);
  1115. // Substitute various strings into the above template
  1116. Replaceall(proxy_class_code, "$csclassname", proxy_class_name);
  1117. Replaceall(proxy_class_def, "$csclassname", proxy_class_name);
  1118. Replaceall(proxy_class_def, "$module", module_class_name);
  1119. Replaceall(proxy_class_code, "$module", module_class_name);
  1120. Replaceall(proxy_class_def, "$dllimport", dllimport);
  1121. Replaceall(proxy_class_code, "$dllimport", dllimport);
  1122. // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
  1123. if(derived){
  1124. Printv(imclass_cppcasts_code,"\n [DllImport(\"", dllimport, "\", EntryPoint=\"CSharp_", proxy_class_name ,"Upcast", "\")]\n", NIL);
  1125. Printf(imclass_cppcasts_code," public static extern IntPtr $csclassnameUpcast(IntPtr objectRef);\n");
  1126. Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
  1127. Printv(upcasts_code,
  1128. "DllExport $cbaseclass * SWIGSTDCALL CSharp_$imclazznameUpcast",
  1129. "($cclass *objectRef) {\n",
  1130. " return ($cbaseclass *)objectRef;\n"
  1131. "}\n",
  1132. "\n",
  1133. NIL);
  1134. Replaceall(upcasts_code, "$cbaseclass", c_baseclass);
  1135. Replaceall(upcasts_code, "$imclazzname", proxy_class_name);
  1136. Replaceall(upcasts_code, "$cclass", c_classname);
  1137. }
  1138. Delete(baseclass);
  1139. }
  1140. /* ----------------------------------------------------------------------
  1141. * classHandler()
  1142. * ---------------------------------------------------------------------- */
  1143. virtual int classHandler(Node *n) {
  1144. File *f_proxy = NULL;
  1145. if (proxy_flag) {
  1146. proxy_class_name = NewString(Getattr(n,"sym:name"));
  1147. if (!addSymbol(proxy_class_name,n)) return SWIG_ERROR;
  1148. if (Cmp(proxy_class_name, imclass_name) == 0) {
  1149. Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
  1150. SWIG_exit(EXIT_FAILURE);
  1151. }
  1152. if (Cmp(proxy_class_name, module_class_name) == 0) {
  1153. Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
  1154. SWIG_exit(EXIT_FAILURE);
  1155. }
  1156. String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), proxy_class_name);
  1157. f_proxy = NewFile(filen,"w");
  1158. if(!f_proxy) {
  1159. Printf(stderr, "Unable to create proxy class file: %s\n", filen);
  1160. SWIG_exit(EXIT_FAILURE);
  1161. }
  1162. Delete(filen); filen = NULL;
  1163. // Start writing out the proxy class file
  1164. emitBanner(f_proxy);
  1165. if(Len(namespce) > 0)
  1166. Printf(f_proxy, "namespace %s {\n", namespce);
  1167. Clear(proxy_class_def);
  1168. Clear(proxy_class_code);
  1169. have_default_constructor_flag = false;
  1170. destructor_call = NewString("");
  1171. proxy_class_constants_code = NewString("");
  1172. }
  1173. Language::classHandler(n);
  1174. if (proxy_flag) {
  1175. emitProxyClassDefAndCPPCasts(n);
  1176. Replaceall(proxy_class_def, "$module", module_class_name);
  1177. Replaceall(proxy_class_code, "$module", module_class_name);
  1178. Replaceall(proxy_class_constants_code, "$module", module_class_name);
  1179. Replaceall(proxy_class_def, "$dllimport", dllimport);
  1180. Replaceall(proxy_class_code, "$dllimport", dllimport);
  1181. Replaceall(proxy_class_constants_code, "$dllimport", dllimport);
  1182. Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
  1183. // Write out all the constants
  1184. if (Len(proxy_class_constants_code) != 0 )
  1185. Printv(f_proxy, proxy_class_constants_code, NIL);
  1186. Printf(f_proxy, "}\n");
  1187. Printf(f_proxy, Len(namespce) > 0 ? "\n}\n" : "");
  1188. Close(f_proxy);
  1189. f_proxy = NULL;
  1190. Delete(proxy_class_name); proxy_class_name = NULL;
  1191. Delete(destructor_call); destructor_call = NULL;
  1192. Delete(proxy_class_constants_code); proxy_class_constants_code = NULL;
  1193. }
  1194. return SWIG_OK;
  1195. }
  1196. /* ----------------------------------------------------------------------
  1197. * memberfunctionHandler()
  1198. * ---------------------------------------------------------------------- */
  1199. virtual int memberfunctionHandler(Node *n) {
  1200. Language::memberfunctionHandler(n);
  1201. if (proxy_flag) {
  1202. String *overloaded_name = getOverloadedName(n);
  1203. String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
  1204. Setattr(n,"proxyfuncname", Getattr(n, "sym:name"));
  1205. Setattr(n,"imfuncname", intermediary_function_name);
  1206. proxyClassFunctionHandler(n);
  1207. Delete(overloaded_name);
  1208. }
  1209. return SWIG_OK;
  1210. }
  1211. /* ----------------------------------------------------------------------
  1212. * staticmemberfunctionHandler()
  1213. * ---------------------------------------------------------------------- */
  1214. virtual int staticmemberfunctionHandler(Node *n) {
  1215. static_flag = true;
  1216. Language::staticmemberfunctionHandler(n);
  1217. if (proxy_flag) {
  1218. String *overloaded_name = getOverloadedName(n);
  1219. String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
  1220. Setattr(n,"proxyfuncname", Getattr(n,"sym:name"));
  1221. Setattr(n,"imfuncname", intermediary_function_name);
  1222. proxyClassFunctionHandler(n);
  1223. Delete(overloaded_name);
  1224. }
  1225. static_flag = false;
  1226. return SWIG_OK;
  1227. }
  1228. /* -----------------------------------------------------------------------------
  1229. * proxyClassFunctionHandler()
  1230. *
  1231. * Function called for creating a C# wrapper function around a c++ function in the
  1232. * proxy class. Used for both static and non-static C++ class functions.
  1233. * C++ class static functions map to C# static functions.
  1234. * Two extra attributes in the Node must be available. These are "proxyfuncname" -
  1235. * the name of the C# class proxy function, which in turn will call "imfuncname" -
  1236. * the intermediary (PInvoke) function name in the intermediary class.
  1237. * ----------------------------------------------------------------------------- */
  1238. void proxyClassFunctionHandler(Node *n) {
  1239. SwigType *t = Getattr(n,"type");
  1240. ParmList *l = Getattr(n,"parms");
  1241. String *intermediary_function_name = Getattr(n,"imfuncname");
  1242. String *proxy_function_name = Getattr(n,"proxyfuncname");
  1243. String *tm;
  1244. Parm *p;
  1245. int i;
  1246. String *imcall = NewString("");
  1247. String *return_type = NewString("");
  1248. String *function_code = NewString("");
  1249. bool setter_flag = false;
  1250. if(!proxy_flag) return;
  1251. // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
  1252. if (Getattr(n, "overload:ignore")) return;
  1253. if (l) {
  1254. if (SwigType_type(Getattr(l,"type")) == T_VOID) {
  1255. l = nextSibling(l);
  1256. }
  1257. }
  1258. /* Attach the non-standard typemaps to the parameter list */
  1259. Swig_typemap_attach_parms("in", l, NULL);
  1260. Swig_typemap_attach_parms("cstype", l, NULL);
  1261. Swig_typemap_attach_parms("csin", l, NULL);
  1262. /* Get return types */
  1263. if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) {
  1264. // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type
  1265. SwigType *virtualtype = Getattr(n,"virtual:type");
  1266. substituteClassname(virtualtype ? virtualtype : t, tm);
  1267. Printf(return_type, "%s", tm);
  1268. if (virtualtype)
  1269. Swig_warning(WARN_CSHARP_COVARIANT_RET, input_file, line_number,
  1270. "Covariant return types not supported in C#. Proxy method will return %s.\n", SwigType_str(virtualtype,0));
  1271. } else {
  1272. Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number,
  1273. "No cstype typemap defined for %s\n", SwigType_str(t,0));
  1274. }
  1275. if(proxy_flag && wrapping_member_flag && !enum_constant_flag) {
  1276. // Properties
  1277. setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) == 0);
  1278. }
  1279. /* Start generating the proxy function */
  1280. const String *methodmods = Getattr(n,"feature:cs:methodmodifiers");
  1281. methodmods = methodmods ? methodmods : (!is_public(n) ? protected_string : public_string);
  1282. Printf(function_code, " %s ", methodmods);
  1283. if (static_flag)
  1284. Printf(function_code, "static ");
  1285. if (Getattr(n,"virtual:derived"))
  1286. Printf(function_code, "override ");
  1287. else if (checkAttribute(n, "storage", "virtual"))
  1288. Printf(function_code, "virtual ");
  1289. Printf(function_code, "%s %s(", return_type, proxy_function_name);
  1290. Printv(imcall, imclass_name, ".", intermediary_function_name, "(", NIL);
  1291. if (!static_flag)
  1292. Printf(imcall, "swigCPtr");
  1293. emit_mark_varargs(l);
  1294. int gencomma = !static_flag;
  1295. /* Output each parameter */
  1296. for (i = 0, p=l; p; i++) {
  1297. /* Ignored varargs */
  1298. if (checkAttribute(p,"varargs:ignore","1")) {
  1299. p = nextSibling(p);
  1300. continue;
  1301. }
  1302. /* Ignored parameters */
  1303. if (checkAttribute(p,"tmap:in:numinputs","0")) {
  1304. p = Getattr(p,"tmap:in:next");
  1305. continue;
  1306. }
  1307. /* Ignore the 'this' argument for variable wrappers */
  1308. if (!(variable_wrapper_flag && i==0))
  1309. {
  1310. SwigType *pt = Getattr(p,"type");
  1311. String *param_type = NewString("");
  1312. /* Get the C# parameter type */
  1313. if ((tm = Getattr(p,"tmap:cstype"))) {
  1314. substituteClassname(pt, tm);
  1315. Printf(param_type, "%s", tm);
  1316. } else {
  1317. Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number,
  1318. "No cstype typemap defined for %s\n", SwigType_str(pt,0));
  1319. }
  1320. if (gencomma)
  1321. Printf(imcall, ", ");
  1322. String *arg = variable_wrapper_flag ? NewString("value") : makeParameterName(n, p, i);
  1323. // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
  1324. if ((tm = Getattr(p,"tmap:csin"))) {
  1325. addThrows(n, "tmap:csin", p);
  1326. substituteClassname(pt, tm);
  1327. Replaceall(tm, "$csinput", arg);
  1328. Printv(imcall, tm, NIL);
  1329. } else {
  1330. Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number,
  1331. "No csin typemap defined for %s\n", SwigType_str(pt,0));
  1332. }
  1333. /* Add parameter to proxy function */
  1334. if (gencomma >= 2)
  1335. Printf(function_code, ", ");
  1336. gencomma = 2;
  1337. Printf(function_code, "%s %s", param_type, arg);
  1338. Delete(arg);
  1339. Delete(param_type);
  1340. }
  1341. p = Getattr(p,"tmap:in:next");
  1342. }
  1343. Printf(imcall, ")");
  1344. Printf(function_code, ")");
  1345. // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
  1346. if ((tm = Swig_typemap_lookup_new("csout",n,"",0))) {
  1347. addThrows(n, "tmap:csout", n);
  1348. if (Getattr(n,"feature:new"))
  1349. Replaceall(tm,"$owner","true");
  1350. else
  1351. Replaceall(tm,"$owner","false");
  1352. substituteClassname(t, tm);
  1353. Replaceall(tm, "$imcall", imcall);
  1354. } else {
  1355. Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number,
  1356. "No csout typemap defined for %s\n", SwigType_str(t,0));
  1357. }
  1358. generateThrowsClause(n, function_code);
  1359. Printf(function_code, " %s\n\n", tm ? (const String *)tm : empty_string);
  1360. if(proxy_flag && wrapping_member_flag && !enum_constant_flag) {
  1361. // Properties
  1362. if(setter_flag) {
  1363. // Setter method
  1364. if ((tm = Swig_typemap_lookup_new("csvarin",n,"",0))) {
  1365. if (Getattr(n,"feature:new"))
  1366. Replaceall(tm,"$owner","true");
  1367. else
  1368. Replaceall(tm,"$owner","false");
  1369. substituteClassname(t, tm);
  1370. Replaceall(tm, "$imcall", imcall);
  1371. Printf(proxy_class_code, "%s", tm);
  1372. } else {
  1373. Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number,
  1374. "No csvarin typemap defined for %s\n", SwigType_str(t,0));
  1375. }
  1376. } else {
  1377. // Getter method
  1378. if ((tm = Swig_typemap_lookup_new("csvarout",n,"",0))) {
  1379. if (Getattr(n,"feature:new"))
  1380. Replaceall(tm,"$owner","true");
  1381. else
  1382. Replaceall(tm,"$owner","false");
  1383. substituteClassname(t, tm);
  1384. Replaceall(tm, "$imcall", imcall);
  1385. Printf(proxy_class_code, "%s", tm);
  1386. } else {
  1387. Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number,
  1388. "No csvarout typemap defined for %s\n", SwigType_str(t,0));
  1389. }
  1390. }
  1391. } else {
  1392. // Normal function call
  1393. Printv(proxy_class_code, function_code, NIL);
  1394. }
  1395. Delete(function_code);
  1396. Delete(return_type);
  1397. Delete(imcall);
  1398. }
  1399. /* ----------------------------------------------------------------------
  1400. * constructorHandler()
  1401. * ---------------------------------------------------------------------- */
  1402. virtual int constructorHandler(Node *n) {
  1403. ParmList *l = Getattr(n,"parms");
  1404. String *tm;
  1405. Parm *p;
  1406. int i;
  1407. Language::constructorHandler(n);
  1408. // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
  1409. if (Getattr(n, "overload:ignore"))
  1410. return SWIG_OK;
  1411. if(proxy_flag) {
  1412. String *overloaded_name = getOverloadedName(n);
  1413. String *imcall = NewString("");
  1414. const String *methodmods = Getattr(n,"feature:cs:methodmodifiers");
  1415. methodmods = methodmods ? methodmods : (!is_public(n) ? protected_string : public_string);
  1416. methodmods = methodmods ? methodmods : public_string;
  1417. Printf(proxy_class_code, " %s %s(", methodmods, proxy_class_name);
  1418. Printv(imcall, " : this(", imclass_name, ".", Swig_name_construct(overloaded_name), "(", NIL);
  1419. /* Attach the non-standard typemaps to the parameter list */
  1420. Swig_typemap_attach_parms("in", l, NULL);
  1421. Swig_typemap_attach_parms("cstype", l, NULL);
  1422. Swig_typemap_attach_parms("csin", l, NULL);
  1423. emit_mark_varargs(l);
  1424. int gencomma = 0;
  1425. /* Output each parameter */
  1426. for (i = 0, p=l; p; i++) {
  1427. /* Ignored varargs */
  1428. if (checkAttribute(p,"varargs:ignore","1")) {
  1429. p = nextSibling(p);
  1430. continue;
  1431. }
  1432. /* Ignored parameters */
  1433. if (checkAttribute(p,"tmap:in:numinputs","0")) {
  1434. p = Getattr(p,"tmap:in:next");
  1435. continue;
  1436. }
  1437. SwigType *pt = Getattr(p,"type");
  1438. String *param_type = NewString("");
  1439. /* Get the C# parameter type */
  1440. if ((tm = Getattr(p,"tmap:cstype"))) {
  1441. substituteClassname(pt, tm);
  1442. Printf(param_type, "%s", tm);
  1443. } else {
  1444. Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number,
  1445. "No cstype typemap defined for %s\n", SwigType_str(pt,0));
  1446. }
  1447. if (gencomma)
  1448. Printf(imcall, ", ");
  1449. String *arg = makeParameterName(n, p, i);
  1450. // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
  1451. if ((tm = Getattr(p,"tmap:csin"))) {
  1452. addThrows(n, "tmap:csin", p);
  1453. substituteClassname(pt, tm);
  1454. Replaceall(tm, "$csinput", arg);
  1455. Printv(imcall, tm, NIL);
  1456. } else {
  1457. Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number,
  1458. "No csin typemap defined for %s\n", SwigType_str(pt,0));
  1459. }
  1460. /* Add parameter to proxy function */
  1461. if(gencomma)
  1462. Printf(proxy_class_code, ", ");
  1463. Printf(proxy_class_code, "%s %s", param_type, arg);
  1464. gencomma = 1;
  1465. Delete(arg);
  1466. Delete(param_type);
  1467. p = Getattr(p,"tmap:in:next");
  1468. }
  1469. Printf(imcall, "), true)");
  1470. Printf(proxy_class_code, ")");
  1471. Printf(proxy_class_code,"%s", imcall);
  1472. generateThrowsClause(n, proxy_class_code);
  1473. Printf(proxy_class_code, " {\n");
  1474. Printf(proxy_class_code, " }\n\n");
  1475. if(!gencomma) // We must have a default constructor
  1476. have_default_constructor_flag = true;
  1477. Delete(overloaded_name);
  1478. Delete(imcall);
  1479. }
  1480. return SWIG_OK;
  1481. }
  1482. /* ----------------------------------------------------------------------
  1483. * destructorHandler(