1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * lang.cxx
6 *
7 * Language base class functions.  Default C++ handling is also implemented here.
8 * ----------------------------------------------------------------------------- */
9
10char cvsroot_lang_cxx[] = "$Id: lang.cxx 11482 2009-07-30 18:48:14Z wsfulton $";
11
12#include "swigmod.h"
13#include "cparse.h"
14#include <ctype.h>
15
16/* default mode settings */
17static int director_mode = 0;
18static int director_protected_mode = 1;
19static int all_protected_mode = 0;
20static int naturalvar_mode = 0;
21Language* Language::this_ = 0;
22
23/* Set director_protected_mode */
24void Wrapper_director_mode_set(int flag) {
25  director_mode = flag;
26}
27
28void Wrapper_director_protected_mode_set(int flag) {
29  director_protected_mode = flag;
30}
31
32void Wrapper_all_protected_mode_set(int flag) {
33  all_protected_mode = flag;
34}
35
36void Wrapper_naturalvar_mode_set(int flag) {
37  naturalvar_mode = flag;
38}
39
40extern "C" {
41  int Swig_director_mode() {
42    return director_mode;
43  }
44  int Swig_director_protected_mode() {
45    return director_protected_mode;
46  }
47  int Swig_all_protected_mode() {
48    return all_protected_mode;
49  }
50  void Language_replace_special_variables(String *method, String *tm, Parm *parm) {
51  Language::instance()->replaceSpecialVariables(method, tm, parm);
52  }
53}
54
55/* Some status variables used during parsing */
56static int InClass = 0; /* Parsing C++ or not */
57static String *ClassName = 0;	/* This is the real name of the current class */
58static String *ClassPrefix = 0;	/* Class prefix */
59static String *ClassType = 0;	/* Fully qualified type name to use */
60static String *DirectorClassName = 0;	/* Director name of the current class */
61int Abstract = 0;
62int ImportMode = 0;
63int IsVirtual = 0;
64static String *AttributeFunctionGet = 0;
65static String *AttributeFunctionSet = 0;
66static Node *CurrentClass = 0;
67int line_number = 0;
68String *input_file = 0;
69int SmartPointer = 0;
70static Hash *classhash;
71
72extern int GenerateDefault;
73extern int ForceExtern;
74extern int AddExtern;
75
76/* import modes */
77
78#define  IMPORT_MODE     1
79#define  IMPORT_MODULE   2
80
81/* ----------------------------------------------------------------------
82 * Dispatcher::emit_one()
83 *
84 * Dispatch a single node
85 * ---------------------------------------------------------------------- */
86
87int Dispatcher::emit_one(Node *n) {
88  String *wrn;
89  int ret = SWIG_OK;
90
91  char *tag = Char(nodeType(n));
92  if (!tag) {
93    /* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree
94       node!\n"); */
95    return SWIG_OK;
96  }
97
98  /* Do not proceed if marked with an error */
99
100  if (Getattr(n, "error"))
101    return SWIG_OK;
102
103  /* Look for warnings */
104  wrn = Getattr(n, "feature:warnfilter");
105  if (wrn) {
106    Swig_warnfilter(wrn, 1);
107  }
108
109  /* ============================================================
110   * C/C++ parsing
111   * ============================================================ */
112
113  if (strcmp(tag, "extern") == 0) {
114    ret = externDeclaration(n);
115  } else if (strcmp(tag, "cdecl") == 0) {
116    ret = cDeclaration(n);
117  } else if (strcmp(tag, "enum") == 0) {
118    ret = enumDeclaration(n);
119  } else if (strcmp(tag, "enumitem") == 0) {
120    ret = enumvalueDeclaration(n);
121  } else if (strcmp(tag, "enumforward") == 0) {
122    ret = enumforwardDeclaration(n);
123  } else if (strcmp(tag, "class") == 0) {
124    ret = classDeclaration(n);
125  } else if (strcmp(tag, "classforward") == 0) {
126    ret = classforwardDeclaration(n);
127  } else if (strcmp(tag, "constructor") == 0) {
128    ret = constructorDeclaration(n);
129  } else if (strcmp(tag, "destructor") == 0) {
130    ret = destructorDeclaration(n);
131  } else if (strcmp(tag, "access") == 0) {
132    ret = accessDeclaration(n);
133  } else if (strcmp(tag, "using") == 0) {
134    ret = usingDeclaration(n);
135  } else if (strcmp(tag, "namespace") == 0) {
136    ret = namespaceDeclaration(n);
137  } else if (strcmp(tag, "template") == 0) {
138    ret = templateDeclaration(n);
139  }
140
141  /* ===============================================================
142   *  SWIG directives
143   * =============================================================== */
144
145  else if (strcmp(tag, "top") == 0) {
146    ret = top(n);
147  } else if (strcmp(tag, "extend") == 0) {
148    ret = extendDirective(n);
149  } else if (strcmp(tag, "apply") == 0) {
150    ret = applyDirective(n);
151  } else if (strcmp(tag, "clear") == 0) {
152    ret = clearDirective(n);
153  } else if (strcmp(tag, "constant") == 0) {
154    ret = constantDirective(n);
155  } else if (strcmp(tag, "fragment") == 0) {
156    ret = fragmentDirective(n);
157  } else if (strcmp(tag, "import") == 0) {
158    ret = importDirective(n);
159  } else if (strcmp(tag, "include") == 0) {
160    ret = includeDirective(n);
161  } else if (strcmp(tag, "insert") == 0) {
162    ret = insertDirective(n);
163  } else if (strcmp(tag, "module") == 0) {
164    ret = moduleDirective(n);
165  } else if (strcmp(tag, "native") == 0) {
166    ret = nativeDirective(n);
167  } else if (strcmp(tag, "pragma") == 0) {
168    ret = pragmaDirective(n);
169  } else if (strcmp(tag, "typemap") == 0) {
170    ret = typemapDirective(n);
171  } else if (strcmp(tag, "typemapcopy") == 0) {
172    ret = typemapcopyDirective(n);
173  } else if (strcmp(tag, "typemapitem") == 0) {
174    ret = typemapitemDirective(n);
175  } else if (strcmp(tag, "types") == 0) {
176    ret = typesDirective(n);
177  } else {
178    Printf(stderr, "%s:%d. Unrecognized parse tree node type '%s'\n", input_file, line_number, tag);
179    ret = SWIG_ERROR;
180  }
181  if (wrn) {
182    Swig_warnfilter(wrn, 0);
183  }
184  return ret;
185}
186
187/* ----------------------------------------------------------------------
188 * Dispatcher::emit_children()
189 *
190 * Emit all children that match the given type. type = 0 means all types.
191 * ---------------------------------------------------------------------- */
192
193int Dispatcher::emit_children(Node *n) {
194  Node *c;
195  char *eo = Char(Getattr(n, "feature:emitonlychildren"));
196  for (c = firstChild(n); c; c = nextSibling(c)) {
197    if (eo) {
198      const char *tag = Char(nodeType(c));
199      if (strcmp(tag, "cdecl") == 0) {
200	if (checkAttribute(c, "storage", "typedef"))
201	  tag = "typedef";
202      }
203      if (strstr(eo, tag) == 0) {
204	continue;
205      }
206    }
207    emit_one(c);
208  }
209  return SWIG_OK;
210}
211
212
213/* Stubs for dispatcher class.  We don't do anything by default---up to derived class
214   to fill in traversal code */
215
216int Dispatcher::defaultHandler(Node *) {
217  return SWIG_OK;
218}
219int Dispatcher::extendDirective(Node *n) {
220  return defaultHandler(n);
221}
222int Dispatcher::applyDirective(Node *n) {
223  return defaultHandler(n);
224}
225int Dispatcher::clearDirective(Node *n) {
226  return defaultHandler(n);
227}
228int Dispatcher::constantDirective(Node *n) {
229  return defaultHandler(n);
230}
231int Dispatcher::fragmentDirective(Node *n) {
232  return defaultHandler(n);
233}
234int Dispatcher::importDirective(Node *n) {
235  return defaultHandler(n);
236}
237int Dispatcher::includeDirective(Node *n) {
238  return defaultHandler(n);
239}
240int Dispatcher::insertDirective(Node *n) {
241  return defaultHandler(n);
242}
243int Dispatcher::moduleDirective(Node *n) {
244  return defaultHandler(n);
245}
246int Dispatcher::nativeDirective(Node *n) {
247  return defaultHandler(n);
248}
249int Dispatcher::pragmaDirective(Node *n) {
250  return defaultHandler(n);
251}
252int Dispatcher::typemapDirective(Node *n) {
253  return defaultHandler(n);
254}
255int Dispatcher::typemapitemDirective(Node *n) {
256  return defaultHandler(n);
257}
258int Dispatcher::typemapcopyDirective(Node *n) {
259  return defaultHandler(n);
260}
261int Dispatcher::typesDirective(Node *n) {
262  return defaultHandler(n);
263}
264int Dispatcher::cDeclaration(Node *n) {
265  return defaultHandler(n);
266}
267int Dispatcher::externDeclaration(Node *n) {
268  return defaultHandler(n);
269}
270int Dispatcher::enumDeclaration(Node *n) {
271  return defaultHandler(n);
272}
273int Dispatcher::enumvalueDeclaration(Node *n) {
274  return defaultHandler(n);
275}
276int Dispatcher::enumforwardDeclaration(Node *n) {
277  return defaultHandler(n);
278}
279int Dispatcher::classDeclaration(Node *n) {
280  return defaultHandler(n);
281}
282int Dispatcher::templateDeclaration(Node *n) {
283  return defaultHandler(n);
284}
285int Dispatcher::classforwardDeclaration(Node *n) {
286  return defaultHandler(n);
287}
288int Dispatcher::constructorDeclaration(Node *n) {
289  return defaultHandler(n);
290}
291int Dispatcher::destructorDeclaration(Node *n) {
292  return defaultHandler(n);
293}
294int Dispatcher::accessDeclaration(Node *n) {
295  return defaultHandler(n);
296}
297int Dispatcher::usingDeclaration(Node *n) {
298  return defaultHandler(n);
299}
300int Dispatcher::namespaceDeclaration(Node *n) {
301  return defaultHandler(n);
302}
303
304
305/* Allocators */
306Language::Language():
307none_comparison(NewString("$arg != 0")),
308director_ctor_code(NewString("")),
309director_prot_ctor_code(0),
310symbols(NewHash()),
311classtypes(NewHash()),
312enumtypes(NewHash()),
313overloading(0),
314multiinput(0),
315cplus_runtime(0),
316directors(0) {
317  argc_template_string = NewString("argc");
318  argv_template_string = NewString("argv[%d]");
319
320  /* Default director constructor code, passed to Swig_ConstructorToFunction */
321  Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", "  $director_new \n", "} else {\n", "  $nondirector_new \n", "}\n", NIL);
322
323  /*
324     Default director 'protected' constructor code, disabled by
325     default. Each language that needs it, has to define it.
326   */
327  director_prot_ctor_code = 0;
328  director_multiple_inheritance = 1;
329  director_language = 0;
330  assert(!this_);
331  this_ = this;
332}
333
334Language::~Language() {
335  Delete(symbols);
336  Delete(classtypes);
337  Delete(enumtypes);
338  Delete(director_ctor_code);
339  Delete(none_comparison);
340  this_ = 0;
341}
342
343/* ----------------------------------------------------------------------
344   emit_one()
345   ---------------------------------------------------------------------- */
346
347int Language::emit_one(Node *n) {
348  int ret;
349  int oldext;
350  if (!n)
351    return SWIG_OK;
352
353  if (GetFlag(n, "feature:ignore")
354      && !Getattr(n, "feature:onlychildren"))
355    return SWIG_OK;
356
357  oldext = Extend;
358  if (Getattr(n, "feature:extend"))
359    Extend = 1;
360
361  line_number = Getline(n);
362  input_file = Getfile(n);
363
364  /*
365     symtab = Getattr(n,"symtab");
366     if (symtab) {
367     symtab = Swig_symbol_setscope(symtab);
368     }
369   */
370  ret = Dispatcher::emit_one(n);
371  /*
372     if (symtab) {
373     Swig_symbol_setscope(symtab);
374     }
375   */
376  Extend = oldext;
377  return ret;
378}
379
380
381static Parm *nonvoid_parms(Parm *p) {
382  if (p) {
383    SwigType *t = Getattr(p, "type");
384    if (SwigType_type(t) == T_VOID)
385      return 0;
386  }
387  return p;
388}
389
390/* -----------------------------------------------------------------------------
391 * cplus_value_type()
392 *
393 * Returns the alternative value type needed in C++ for class value
394 * types. When swig is not sure about using a plain $ltype value,
395 * since the class doesn't have a default constructor, or it can't be
396 * assigned, you will get back 'SwigValueWrapper<type >'.
397 *
398 * ----------------------------------------------------------------------------- */
399
400SwigType *cplus_value_type(SwigType *t) {
401  return SwigType_alttype(t, 0);
402}
403
404static Node *first_nontemplate(Node *n) {
405  while (n) {
406    if (Strcmp(nodeType(n), "template") != 0)
407      return n;
408    n = Getattr(n, "sym:nextSibling");
409  }
410  return n;
411}
412
413
414
415/* --------------------------------------------------------------------------
416 * swig_pragma()
417 *
418 * Handle swig pragma directives.
419 * -------------------------------------------------------------------------- */
420
421void swig_pragma(char *lang, char *name, char *value) {
422  if (strcmp(lang, "swig") == 0) {
423    if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) {
424      GenerateDefault = 1;
425    } else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) {
426      Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n");
427      GenerateDefault = 0;
428    } else if (strcmp(name, "attributefunction") == 0) {
429      String *nvalue = NewString(value);
430      char *s = strchr(Char(nvalue), ':');
431      if (!s) {
432	Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
433      } else {
434	*s = 0;
435	AttributeFunctionGet = NewString(Char(nvalue));
436	AttributeFunctionSet = NewString(s + 1);
437      }
438      Delete(nvalue);
439    } else if (strcmp(name, "noattributefunction") == 0) {
440      AttributeFunctionGet = 0;
441      AttributeFunctionSet = 0;
442    }
443  }
444}
445
446/* --------------------------------------------------------------------------
447 * use_naturalvar_mode()
448 * -------------------------------------------------------------------------- */
449int use_naturalvar_mode(Node *n) {
450  if (Getattr(n, "unnamed"))
451    return 0;
452  int nvar = naturalvar_mode || GetFlag(n, "feature:naturalvar");
453  if (!nvar) {
454    /* look for feature in the class */
455    SwigType *ty = Getattr(n, "type");
456    SwigType *fullty = SwigType_typedef_resolve_all(ty);
457    if (SwigType_isclass(fullty)) {
458      Node *m = Copy(n);
459      SwigType *tys = SwigType_strip_qualifiers(fullty);
460      Swig_features_get(Swig_cparse_features(), 0, tys, 0, m);
461      nvar = GetFlag(m, "feature:naturalvar");
462      Delete(tys);
463      Delete(m);
464    }
465    Delete(fullty);
466  }
467  return nvar ? CWRAP_NATURAL_VAR : 0;
468}
469
470/* ----------------------------------------------------------------------
471 * Language::top()   - Top of parsing tree
472 * ---------------------------------------------------------------------- */
473
474int Language::top(Node *n) {
475  Node *mod = Getattr(n, "module");
476  if (mod) {
477    Node *options = Getattr(mod, "options");
478    if (options) {
479      if (Getattr(options, "naturalvar")) {
480	naturalvar_mode = 1;
481      }
482      if (Getattr(options, "nonaturalvar")) {
483	naturalvar_mode = 0;
484      }
485    }
486  }
487  classhash = Getattr(n, "classes");
488  return emit_children(n);
489}
490
491/* ----------------------------------------------------------------------
492 * Language::extendDirective()
493 * ---------------------------------------------------------------------- */
494
495int Language::extendDirective(Node *n) {
496  int oldam = Extend;
497  AccessMode oldmode = cplus_mode;
498  Extend = CWRAP_EXTEND;
499  cplus_mode = PUBLIC;
500
501  emit_children(n);
502
503  Extend = oldam;
504  cplus_mode = oldmode;
505  return SWIG_OK;
506}
507
508/* ----------------------------------------------------------------------
509 * Language::applyDirective()
510 * ---------------------------------------------------------------------- */
511
512int Language::applyDirective(Node *n) {
513
514  Parm *pattern = Getattr(n, "pattern");
515  Node *c = firstChild(n);
516  while (c) {
517    Parm *apattern = Getattr(c, "pattern");
518    if (ParmList_len(pattern) != ParmList_len(apattern)) {
519      Swig_error(input_file, line_number, "Can't apply (%s) to (%s).  Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern));
520    } else {
521      if (!Swig_typemap_apply(pattern, apattern)) {
522	Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
523      }
524    }
525    c = nextSibling(c);
526  }
527  return SWIG_OK;
528}
529
530/* ----------------------------------------------------------------------
531 * Language::clearDirective()
532 * ---------------------------------------------------------------------- */
533
534int Language::clearDirective(Node *n) {
535  Node *p;
536  for (p = firstChild(n); p; p = nextSibling(p)) {
537    ParmList *pattern = Getattr(p, "pattern");
538    Swig_typemap_clear_apply(pattern);
539  }
540  return SWIG_OK;
541}
542
543/* ----------------------------------------------------------------------
544 * Language::constantDirective()
545 * ---------------------------------------------------------------------- */
546
547int Language::constantDirective(Node *n) {
548
549  if (CurrentClass && (cplus_mode != PUBLIC))
550    return SWIG_NOWRAP;
551
552  if (!GetFlag(n, "feature:allowexcept")) {
553    UnsetFlag(n, "feature:except");
554  }
555  if (Getattr(n, "feature:exceptvar")) {
556    Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
557  }
558
559  if (!ImportMode) {
560    Swig_require("constantDirective", n, "name", "?value", NIL);
561    String *name = Getattr(n, "name");
562    String *value = Getattr(n, "value");
563    if (!value) {
564      value = Copy(name);
565    } else {
566      /*      if (checkAttribute(n,"type","char")) {
567         value = NewString(value);
568         } else {
569         value = NewStringf("%(escape)s", value);
570         }
571       */
572      Setattr(n, "rawvalue", value);
573      value = NewStringf("%(escape)s", value);
574      if (!Len(value))
575	Append(value, "\\0");
576      /*      Printf(stdout,"'%s' = '%s'\n", name, value); */
577    }
578    Setattr(n, "value", value);
579    this->constantWrapper(n);
580    Swig_restore(n);
581    return SWIG_OK;
582  }
583  return SWIG_NOWRAP;
584}
585
586/* ----------------------------------------------------------------------
587 * Language::fragmentDirective()
588 * ---------------------------------------------------------------------- */
589
590int Language::fragmentDirective(Node *n) {
591  Swig_fragment_register(n);
592  return SWIG_OK;
593}
594
595/* ----------------------------------------------------------------------
596 * Language::importDirective()
597 * ---------------------------------------------------------------------- */
598
599int Language::importDirective(Node *n) {
600  int oldim = ImportMode;
601  ImportMode = IMPORT_MODE;
602  emit_children(n);
603  ImportMode = oldim;
604  return SWIG_OK;
605}
606
607/* ----------------------------------------------------------------------
608 * Language::includeDirective()
609 * ---------------------------------------------------------------------- */
610
611int Language::includeDirective(Node *n) {
612  emit_children(n);
613  return SWIG_OK;
614}
615
616/* ----------------------------------------------------------------------
617 * Language::insertDirective()
618 * ---------------------------------------------------------------------- */
619
620int Language::insertDirective(Node *n) {
621  /* %insert directive */
622  if ((!ImportMode) || Getattr(n, "generated")) {
623    String *code = Getattr(n, "code");
624    String *section = Getattr(n, "section");
625    File *f = 0;
626    if (!section) {		/* %{ ... %} */
627      f = Swig_filebyname("header");
628    } else {
629      f = Swig_filebyname(section);
630    }
631    if (f) {
632      Printf(f, "%s\n", code);
633    } else {
634      Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section);
635    }
636    return SWIG_OK;
637  } else {
638    return SWIG_NOWRAP;
639  }
640}
641
642/* ----------------------------------------------------------------------
643 * Language::moduleDirective()
644 * ---------------------------------------------------------------------- */
645
646int Language::moduleDirective(Node *n) {
647  (void) n;
648  /* %module directive */
649  return SWIG_OK;
650}
651
652/* ----------------------------------------------------------------------
653 * Language::nativeDirective()
654 * ---------------------------------------------------------------------- */
655
656int Language::nativeDirective(Node *n) {
657  if (!ImportMode) {
658    return nativeWrapper(n);
659  } else {
660    return SWIG_NOWRAP;
661  }
662}
663
664/* ----------------------------------------------------------------------
665 * Language::pragmaDirective()
666 * ---------------------------------------------------------------------- */
667
668int Language::pragmaDirective(Node *n) {
669  /* %pragma directive */
670  if (!ImportMode) {
671    String *lan = Getattr(n, "lang");
672    String *name = Getattr(n, "name");
673    String *value = Getattr(n, "value");
674    swig_pragma(Char(lan), Char(name), Char(value));
675    /*  pragma(Char(lan),Char(name),Char(value)); */
676    return SWIG_OK;
677  }
678  return SWIG_OK;
679}
680
681/* ----------------------------------------------------------------------
682 * Language::typemapDirective()
683 * ---------------------------------------------------------------------- */
684
685int Language::typemapDirective(Node *n) {
686  /* %typemap directive */
687  String *method = Getattr(n, "method");
688  String *code = Getattr(n, "code");
689  Parm *kwargs = Getattr(n, "kwargs");
690  Node *items = firstChild(n);
691  static int namewarn = 0;
692
693
694  if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
695    Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "Deprecated typemap feature ($source/$target).\n");
696    if (!namewarn) {
697      Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is deprecated.\n\
698For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
699$source by $input and $target by $1.   For typemaps related to return values (out,\n\
700argout,ret,except), replace $source by $1 and $target by $result.  See the file\n\
701Doc/Manual/Typemaps.html for complete details.\n");
702      namewarn = 1;
703    }
704  }
705
706  if (Strcmp(method, "except") == 0) {
707    Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n");
708  }
709
710  if (Strcmp(method, "in") == 0) {
711    Hash *k;
712    k = kwargs;
713    while (k) {
714      if (checkAttribute(k, "name", "numinputs")) {
715	if (!multiinput && (GetInt(k, "value") > 1)) {
716	  Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
717	  return SWIG_ERROR;
718	}
719	break;
720      }
721      k = nextSibling(k);
722    }
723    if (!k) {
724      k = NewHash();
725      Setattr(k, "name", "numinputs");
726      Setattr(k, "value", "1");
727      set_nextSibling(k, kwargs);
728      Setattr(n, "kwargs", k);
729      kwargs = k;
730    }
731  }
732
733  if (Strcmp(method, "ignore") == 0) {
734    Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
735
736    Clear(method);
737    Append(method, "in");
738    Hash *k = NewHash();
739    Setattr(k, "name", "numinputs");
740    Setattr(k, "value", "0");
741    set_nextSibling(k, kwargs);
742    Setattr(n, "kwargs", k);
743    kwargs = k;
744  }
745
746  /* Replace $descriptor() macros */
747
748  if (code) {
749    Setfile(code, Getfile(n));
750    Setline(code, Getline(n));
751    Swig_cparse_replace_descriptor(code);
752  }
753
754  while (items) {
755    Parm *pattern = Getattr(items, "pattern");
756    Parm *parms = Getattr(items, "parms");
757
758    if (code) {
759      Swig_typemap_register(method, pattern, code, parms, kwargs);
760    } else {
761      Swig_typemap_clear(method, pattern);
762    }
763    items = nextSibling(items);
764  }
765  return SWIG_OK;
766
767}
768
769/* ----------------------------------------------------------------------
770 * Language::typemapcopyDirective()
771 * ---------------------------------------------------------------------- */
772
773int Language::typemapcopyDirective(Node *n) {
774  String *method = Getattr(n, "method");
775  Parm *pattern = Getattr(n, "pattern");
776  Node *items = firstChild(n);
777  int nsrc = 0;
778  nsrc = ParmList_len(pattern);
779  while (items) {
780    ParmList *npattern = Getattr(items, "pattern");
781    if (nsrc != ParmList_len(npattern)) {
782      Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n");
783    } else {
784      if (Swig_typemap_copy(method, pattern, npattern) < 0) {
785	Swig_error(input_file, line_number, "Can't copy typemap.\n");
786      }
787    }
788    items = nextSibling(items);
789  }
790  return SWIG_OK;
791}
792
793/* ----------------------------------------------------------------------
794 * Language::typesDirective()
795 * ---------------------------------------------------------------------- */
796
797int Language::typesDirective(Node *n) {
798  Parm *parms = Getattr(n, "parms");
799  String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */
800  while (parms) {
801    SwigType *t = Getattr(parms, "type");
802    String *v = Getattr(parms, "value");
803    if (!v) {
804      SwigType_remember(t);
805    } else {
806      if (SwigType_issimple(t)) {
807	SwigType_inherit(t, v, 0, convcode);
808      }
809    }
810    parms = nextSibling(parms);
811  }
812  return SWIG_OK;
813}
814
815/* ----------------------------------------------------------------------
816 * Language::cDeclaration()
817 * ---------------------------------------------------------------------- */
818
819int Language::cDeclaration(Node *n) {
820
821  String *name = Getattr(n, "name");
822  String *symname = Getattr(n, "sym:name");
823  SwigType *type = Getattr(n, "type");
824  SwigType *decl = Getattr(n, "decl");
825  String *storage = Getattr(n, "storage");
826  Node *over;
827  File *f_header = 0;
828  SwigType *ty, *fullty;
829
830  /* discards nodes following the access control rules */
831  if (cplus_mode != PUBLIC || !is_public(n)) {
832    /* except for friends, they are not affected by access control */
833    int isfriend = storage && (Cmp(storage, "friend") == 0);
834    if (!isfriend) {
835      /* Check what the director needs. If the method is pure virtual, it is always needed.
836       * Also wrap non-virtual protected members if asked for (allprotected mode). */
837      if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || is_non_virtual_protected_access(n)))) {
838          return SWIG_NOWRAP;
839      }
840      // Prevent wrapping protected overloaded director methods more than once -
841      // This bit of code is only needed due to the cDeclaration call in classHandler()
842      String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname"));
843      if (Getattr(CurrentClass, wrapname)) {
844	Delete(wrapname);
845	return SWIG_NOWRAP;
846      }
847      SetFlag(CurrentClass, wrapname);
848      Delete(wrapname);
849    }
850  }
851
852  if (Cmp(storage, "typedef") == 0) {
853    Swig_save("cDeclaration", n, "type", NIL);
854    SwigType *t = Copy(type);
855    if (t) {
856      SwigType_push(t, decl);
857      Setattr(n, "type", t);
858      typedefHandler(n);
859    }
860    Swig_restore(n);
861    return SWIG_OK;
862  }
863
864  /* If in import mode, we proceed no further */
865  if (ImportMode)
866    return SWIG_NOWRAP;
867
868  /* If we're in extend mode and there is code, replace the $descriptor macros */
869  if (Extend) {
870    String *code = Getattr(n, "code");
871    if (code) {
872      Setfile(code, Getfile(n));
873      Setline(code, Getline(n));
874      Swig_cparse_replace_descriptor(code);
875    }
876  }
877
878  /* Overloaded symbol check */
879  over = Swig_symbol_isoverloaded(n);
880  if (!overloading) {
881    if (over)
882      over = first_nontemplate(over);
883    if (over && (over != n)) {
884      Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored.  %s\n", Swig_name_decl(n));
885      Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", Swig_name_decl(over));
886      return SWIG_NOWRAP;
887    }
888  }
889
890  if (symname && !validIdentifier(symname)) {
891    Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", symname);
892    return SWIG_NOWRAP;
893  }
894
895  ty = NewString(type);
896  SwigType_push(ty, decl);
897  fullty = SwigType_typedef_resolve_all(ty);
898  if (SwigType_isfunction(fullty)) {
899    if (!SwigType_isfunction(ty)) {
900      Delete(ty);
901      ty = fullty;
902      fullty = 0;
903      ParmList *parms = SwigType_function_parms(ty);
904      Setattr(n, "parms", parms);
905    }
906    /* Transform the node into a 'function' node and emit */
907    if (!CurrentClass) {
908      f_header = Swig_filebyname("header");
909
910      if (AddExtern) {
911	if (f_header) {
912	  if ((Cmp(storage, "extern") == 0) || (ForceExtern && !storage)) {
913	    /* we don't need the 'extern' part in the C/C++ declaration,
914	       and it produces some problems when namespace and SUN
915	       Studio is used.
916
917	       Printf(f_header,"extern %s", SwigType_str(ty,name));
918
919	       In fact generating extern declarations is quite error prone and is
920	       no longer the default. Getting it right seems impossible with namespaces
921	       and default arguments and when a method is declared with the various Windows
922	       calling conventions - SWIG doesn't understand Windows (non standard) calling
923	       conventions in the first place, so can't regenerate them.
924	     */
925	    String *str = SwigType_str(ty, name);
926	    Printf(f_header, "%s", str);
927	    Delete(str);
928	    {
929	      DOH *t = Getattr(n, "throws");
930	      if (t) {
931		Printf(f_header, " throw(");
932		while (t) {
933		  Printf(f_header, "%s", Getattr(t, "type"));
934		  t = nextSibling(t);
935		  if (t)
936		    Printf(f_header, ",");
937		}
938		Printf(f_header, ")");
939	      }
940	    }
941	    Printf(f_header, ";\n");
942	  } else if (Cmp(storage, "externc") == 0) {
943	    /* here 'extern "C"' is needed */
944	    String *str = SwigType_str(ty, name);
945	    Printf(f_header, "extern \"C\" %s;\n", str);
946	    Delete(str);
947	  }
948	}
949      }
950    }
951    /* This needs to check qualifiers */
952    if (SwigType_isqualifier(ty)) {
953      SwigType *qual = SwigType_pop(ty);
954      Setattr(n, "qualifier", qual);
955      Delete(qual);
956    }
957    Delete(SwigType_pop_function(ty));
958    DohIncref(type);
959    Setattr(n, "type", ty);
960    if (GetFlag(n, "feature:onlychildren") && !GetFlag(n, "feature:ignore")) {
961      // Found an unignored templated method that has a an empty template instantiation (%template())
962      // Ignore it unless it has been %rename'd
963      if (Strncmp(symname, "__dummy_", 8) == 0) {
964        SetFlag(n, "feature:ignore");
965        Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
966                     "%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n));
967      }
968    }
969    if (!GetFlag(n, "feature:ignore"))
970      functionHandler(n);
971    Setattr(n, "type", type);
972    Delete(ty);
973    Delete(type);
974    return SWIG_OK;
975  } else {
976    /* Some kind of variable declaration */
977    String *declaration = Copy(decl);
978    Delattr(n, "decl");
979    if (Getattr(n, "nested"))
980      SetFlag(n, "feature:immutable");
981    if (!CurrentClass) {
982      if ((Cmp(storage, "extern") == 0) || ForceExtern) {
983	f_header = Swig_filebyname("header");
984	if (AddExtern) {
985	  if (f_header) {
986	    String *str = SwigType_str(ty, name);
987	    Printf(f_header, "extern %s;\n", str);
988	    Delete(str);
989	  }
990	}
991      }
992    }
993    if (!SwigType_ismutable(ty)) {
994      SetFlag(n, "feature:immutable");
995    }
996    /* If an array and elements are const, then read-only */
997    if (SwigType_isarray(ty)) {
998      SwigType *tya = SwigType_array_type(ty);
999      if (SwigType_isconst(tya)) {
1000	SetFlag(n, "feature:immutable");
1001      }
1002      Delete(tya);
1003    }
1004    DohIncref(type);
1005    Setattr(n, "type", ty);
1006    variableHandler(n);
1007    Setattr(n, "type", type);
1008    Setattr(n, "decl", declaration);
1009    Delete(ty);
1010    Delete(type);
1011    Delete(fullty);
1012    return SWIG_OK;
1013  }
1014}
1015
1016/* ----------------------------------------------------------------------
1017 * Language::functionHandler()
1018 * ---------------------------------------------------------------------- */
1019
1020int Language::functionHandler(Node *n) {
1021  String *storage = Getattr(n, "storage");
1022  int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
1023  int isstatic = CurrentClass && Cmp(storage, "static") == 0 && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
1024  Parm *p = Getattr(n, "parms");
1025  if (GetFlag(n, "feature:del")) {
1026    /* the method acts like a delete operator, ie, we need to disown the parameter */
1027    if (CurrentClass && !isstatic && !isfriend) {
1028      SetFlag(n, "feature:self:disown");
1029    } else {
1030      if (p)
1031	SetFlag(p, "wrap:disown");
1032    }
1033  }
1034  if (!CurrentClass) {
1035    globalfunctionHandler(n);
1036  } else {
1037    if (isstatic) {
1038      staticmemberfunctionHandler(n);
1039    } else if (isfriend) {
1040      globalfunctionHandler(n);
1041    } else {
1042      Node *explicit_n = 0;
1043      if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
1044	bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
1045	if (virtual_but_not_pure_virtual) {
1046	  // Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
1047	  explicit_n = Copy(n);
1048	  String *new_symname = Copy(Getattr(n, "sym:name"));
1049	  String *suffix = Getattr(parentNode(n), "sym:name");
1050	  Printv(new_symname, "SwigExplicit", suffix, NIL);
1051	  Setattr(explicit_n, "sym:name", new_symname);
1052	  Delattr(explicit_n, "storage");
1053	  Delattr(explicit_n, "override");
1054	  Delattr(explicit_n, "hides");
1055	  SetFlag(explicit_n, "explicitcall");
1056	  Setattr(n, "explicitcallnode", explicit_n);
1057	}
1058      }
1059
1060      memberfunctionHandler(n);
1061
1062      if (explicit_n) {
1063	memberfunctionHandler(explicit_n);
1064	Delattr(explicit_n, "explicitcall");
1065	Delete(explicit_n);
1066      }
1067    }
1068  }
1069  return SWIG_OK;
1070}
1071
1072/* ----------------------------------------------------------------------
1073 * Language::globalfunctionHandler()
1074 * ---------------------------------------------------------------------- */
1075
1076int Language::globalfunctionHandler(Node *n) {
1077
1078  Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL);
1079
1080  String *name = Getattr(n, "name");
1081  String *symname = Getattr(n, "sym:name");
1082  SwigType *type = Getattr(n, "type");
1083  ParmList *parms = Getattr(n, "parms");
1084
1085  /* Check for callback mode */
1086  String *cb = GetFlagAttr(n, "feature:callback");
1087  if (cb) {
1088    String *cbname = Getattr(n, "feature:callback:name");
1089    if (!cbname) {
1090      cbname = NewStringf(cb, symname);
1091      Setattr(n, "feature:callback:name", cbname);
1092    }
1093
1094    callbackfunctionHandler(n);
1095    if (Cmp(cbname, symname) == 0) {
1096      Delete(cbname);
1097      Swig_restore(n);
1098      return SWIG_NOWRAP;
1099    }
1100    Delete(cbname);
1101  }
1102  Setattr(n, "parms", nonvoid_parms(parms));
1103  String *call = Swig_cfunction_call(name, parms);
1104  String *cres = Swig_cresult(type, "result", call);
1105  Setattr(n, "wrap:action", cres);
1106  Delete(cres);
1107  Delete(call);
1108  functionWrapper(n);
1109
1110  Swig_restore(n);
1111  return SWIG_OK;
1112}
1113
1114/* ----------------------------------------------------------------------
1115 * Language::callbackfunctionHandler()
1116 * ---------------------------------------------------------------------- */
1117
1118int Language::callbackfunctionHandler(Node *n) {
1119  Swig_require("callbackfunctionHandler", n, "name", "*sym:name", "*type", "?value", NIL);
1120  String *symname = Getattr(n, "sym:name");
1121  String *type = Getattr(n, "type");
1122  String *name = Getattr(n, "name");
1123  String *parms = Getattr(n, "parms");
1124  String *cb = GetFlagAttr(n, "feature:callback");
1125  String *cbname = Getattr(n, "feature:callback:name");
1126  String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name));
1127  SwigType *cbty = Copy(type);
1128  SwigType_add_function(cbty, parms);
1129  SwigType_add_pointer(cbty);
1130
1131  if (!cbname) {
1132    cbname = NewStringf(cb, symname);
1133    Setattr(n, "feature:callback:name", cbname);
1134  }
1135
1136  Setattr(n, "sym:name", cbname);
1137  Setattr(n, "type", cbty);
1138  Setattr(n, "value", calltype);
1139
1140  Node *ns = Getattr(symbols, cbname);
1141  if (!ns)
1142    constantWrapper(n);
1143
1144  Delete(cbname);
1145  Delete(cbty);
1146
1147  Swig_restore(n);
1148  return SWIG_OK;
1149}
1150
1151/* ----------------------------------------------------------------------
1152 * Language::memberfunctionHandler()
1153 * ---------------------------------------------------------------------- */
1154
1155int Language::memberfunctionHandler(Node *n) {
1156
1157  Swig_require("memberfunctionHandler", n, "*name", "*sym:name", "*type", "?parms", "?value", NIL);
1158
1159  String *storage = Getattr(n, "storage");
1160  String *name = Getattr(n, "name");
1161  String *symname = Getattr(n, "sym:name");
1162  SwigType *type = Getattr(n, "type");
1163  String *value = Getattr(n, "value");
1164  ParmList *parms = Getattr(n, "parms");
1165  String *cb = GetFlagAttr(n, "feature:callback");
1166
1167  if (Cmp(storage, "virtual") == 0) {
1168    if (Cmp(value, "0") == 0) {
1169      IsVirtual = PURE_VIRTUAL;
1170    } else {
1171      IsVirtual = PLAIN_VIRTUAL;
1172    }
1173  } else {
1174    IsVirtual = 0;
1175  }
1176  if (cb) {
1177    Node *cbn = NewHash();
1178    String *cbname = Getattr(n, "feature:callback:name");
1179    if (!cbname) {
1180      cbname = NewStringf(cb, symname);
1181    }
1182
1183    SwigType *cbty = Copy(type);
1184    SwigType_add_function(cbty, parms);
1185    SwigType_add_memberpointer(cbty, ClassName);
1186    String *cbvalue = NewStringf("&%s::%s", ClassName, name);
1187    Setattr(cbn, "sym:name", cbname);
1188    Setattr(cbn, "type", cbty);
1189    Setattr(cbn, "value", cbvalue);
1190    Setattr(cbn, "name", name);
1191
1192    memberconstantHandler(cbn);
1193    Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname));
1194
1195    Delete(cb);
1196    Delete(cbn);
1197    Delete(cbvalue);
1198    Delete(cbty);
1199    Delete(cbname);
1200    if (Cmp(cbname, symname) == 0) {
1201      Swig_restore(n);
1202      return SWIG_NOWRAP;
1203    }
1204  }
1205
1206  String *fname = Swig_name_member(ClassPrefix, symname);
1207  if (Extend && SmartPointer) {
1208    if (!Getattr(n, "classname")) {
1209      Setattr(n, "classname", Getattr(CurrentClass, "allocate:smartpointerbase"));
1210    }
1211  }
1212  // Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
1213  // Note: protected director methods or when allprotected mode turned on.
1214  String *director_type = 0;
1215  if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || is_non_virtual_protected_access(n))) {
1216    director_type = Copy(DirectorClassName);
1217    String *qualifier = Getattr(n, "qualifier");
1218    if (qualifier)
1219      SwigType_push(director_type, qualifier);
1220    SwigType_add_pointer(director_type);
1221  }
1222
1223  int DirectorExtraCall = 0;
1224  if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer)
1225    if (extraDirectorProtectedCPPMethodsRequired())
1226      DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
1227
1228  if (GetFlag(n, "explicitcall"))
1229    DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
1230
1231  Swig_MethodToFunction(n, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type,
1232			is_member_director(CurrentClass, n));
1233  Setattr(n, "sym:name", fname);
1234
1235  functionWrapper(n);
1236
1237  Delete(director_type);
1238  Delete(fname);
1239  Swig_restore(n);
1240  return SWIG_OK;
1241}
1242
1243/* ----------------------------------------------------------------------
1244 * Language::staticmemberfunctionHandler()
1245 * ---------------------------------------------------------------------- */
1246
1247int Language::staticmemberfunctionHandler(Node *n) {
1248
1249  Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL);
1250  Swig_save("staticmemberfunctionHandler", n, "storage", NIL);
1251  String *name = Getattr(n, "name");
1252  String *symname = Getattr(n, "sym:name");
1253  SwigType *type = Getattr(n, "type");
1254  ParmList *parms = Getattr(n, "parms");
1255  String *cb = GetFlagAttr(n, "feature:callback");
1256  String *cname, *mrename;
1257
1258  if (!Extend) {
1259    Node *sb = Getattr(n, "cplus:staticbase");
1260    String *sname = Getattr(sb, "name");
1261    if (is_non_virtual_protected_access(n))
1262      cname = NewStringf("%s::%s", DirectorClassName, name);
1263    else
1264      cname = NewStringf("%s::%s", sname, name);
1265  } else {
1266    String *mname = Swig_name_mangle(ClassName);
1267    cname = Swig_name_member(mname, name);
1268    Delete(mname);
1269  }
1270  mrename = Swig_name_member(ClassPrefix, symname);
1271
1272  if (Extend) {
1273    String *code = Getattr(n, "code");
1274    String *defaultargs = Getattr(n, "defaultargs");
1275    String *mangled = Swig_name_mangle(mrename);
1276    Delete(mrename);
1277    mrename = mangled;
1278
1279    if (Getattr(n, "sym:overloaded") && code) {
1280      Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
1281    }
1282
1283    if (!defaultargs && code) {
1284      /* Hmmm. An added static member.  We have to create a little wrapper for this */
1285      Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus, 0);
1286    }
1287  }
1288
1289  Setattr(n, "name", cname);
1290  Setattr(n, "sym:name", mrename);
1291
1292  if (cb) {
1293    String *cbname = NewStringf(cb, symname);
1294    Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname));
1295    Setattr(n, "feature:callback:staticname", name);
1296  }
1297  Delattr(n, "storage");
1298
1299  globalfunctionHandler(n);
1300
1301  Delete(cname);
1302  Delete(mrename);
1303  Swig_restore(n);
1304  return SWIG_OK;
1305}
1306
1307/* ----------------------------------------------------------------------
1308 * Language::variableHandler()
1309 * ---------------------------------------------------------------------- */
1310
1311int Language::variableHandler(Node *n) {
1312
1313  /* If not a smart-pointer access or added method. We clear
1314     feature:except.   There is no way C++ or C would throw
1315     an exception merely for accessing a member data.
1316
1317     Caveat:  Some compilers seem to route attribute access through
1318     methods which can generate exceptions.  The feature:allowexcept
1319     allows this. Also, the feature:exceptvar can be used to match
1320     only variables.
1321   */
1322  if (!(Extend | SmartPointer)) {
1323    if (!GetFlag(n, "feature:allowexcept")) {
1324      UnsetFlag(n, "feature:except");
1325    }
1326    if (Getattr(n, "feature:exceptvar")) {
1327      Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
1328    }
1329  }
1330
1331  if (!CurrentClass) {
1332    globalvariableHandler(n);
1333  } else {
1334    String *storage = Getattr(n, "storage");
1335    Swig_save("variableHandler", n, "feature:immutable", NIL);
1336    if (SmartPointer) {
1337      /* If a smart-pointer and it's a constant access, we have to set immutable */
1338      if (Getattr(CurrentClass, "allocate:smartpointerconst")) {
1339	SetFlag(n, "feature:immutable");
1340      }
1341    }
1342    if ((Cmp(storage, "static") == 0) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
1343      staticmembervariableHandler(n);
1344    } else {
1345      membervariableHandler(n);
1346    }
1347    Swig_restore(n);
1348  }
1349  return SWIG_OK;
1350}
1351
1352/* ----------------------------------------------------------------------
1353 * Language::globalvariableHandler()
1354 * ---------------------------------------------------------------------- */
1355
1356int Language::globalvariableHandler(Node *n) {
1357  variableWrapper(n);
1358  return SWIG_OK;
1359}
1360
1361/* ----------------------------------------------------------------------
1362 * Language::membervariableHandler()
1363 * ---------------------------------------------------------------------- */
1364
1365int Language::membervariableHandler(Node *n) {
1366
1367  Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL);
1368  Swig_save("membervariableHandler", n, "parms", NIL);
1369
1370  String *name = Getattr(n, "name");
1371  String *symname = Getattr(n, "sym:name");
1372  SwigType *type = Getattr(n, "type");
1373
1374  if (!AttributeFunctionGet) {
1375    String *mname = Swig_name_member(ClassPrefix, symname);
1376    String *mrename_get = Swig_name_get(mname);
1377    String *mrename_set = Swig_name_set(mname);
1378    Delete(mname);
1379
1380    /* Create a function to set the value of the variable */
1381
1382    int assignable = is_assignable(n);
1383
1384    if (SmartPointer) {
1385      if (Getattr(CurrentClass, "allocate:smartpointerconst")) {
1386	assignable = 0;
1387      }
1388    }
1389
1390    if (assignable) {
1391      int make_set_wrapper = 1;
1392      String *tm = 0;
1393      String *target = 0;
1394      if (!Extend) {
1395	if (SmartPointer) {
1396	  if (checkAttribute(n, "storage", "static")) {
1397	    Node *sn = Getattr(n, "cplus:staticbase");
1398	    String *base = Getattr(sn, "name");
1399	    target = NewStringf("%s::%s", base, name);
1400	  } else {
1401	    String *pname = Swig_cparm_name(0, 0);
1402	    target = NewStringf("(*%s)->%s", pname, name);
1403	    Delete(pname);
1404	  }
1405	} else {
1406	  String *pname = is_non_virtual_protected_access(n) ? NewString("darg") : Swig_cparm_name(0, 0);
1407	  target = NewStringf("%s->%s", pname, name);
1408	  Delete(pname);
1409	}
1410      } else {
1411	 target = NewStringf("$extendgetcall"); // member variable access expanded later
1412      }
1413      tm = Swig_typemap_lookup("memberin", n, target, 0);
1414      int flags = Extend | SmartPointer | use_naturalvar_mode(n);
1415      if (is_non_virtual_protected_access(n))
1416        flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
1417
1418      String *call = 0;
1419      Swig_MembersetToFunction(n, ClassType, flags, &call);
1420      Setattr(n, "memberset", "1");
1421
1422      if (!tm) {
1423	if (SwigType_isarray(type)) {
1424	  Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
1425	  make_set_wrapper = 0;
1426	}
1427      } else {
1428	String *pname0 = Swig_cparm_name(0, 0);
1429	String *pname1 = Swig_cparm_name(0, 1);
1430	Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
1431	Replace(tm, "$target", target, DOH_REPLACE_ANY);
1432	Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
1433	Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
1434	Replace(tm, "$extendgetcall", call, DOH_REPLACE_ANY);
1435	Setattr(n, "wrap:action", tm);
1436	Delete(tm);
1437	Delete(pname0);
1438	Delete(pname1);
1439      }
1440      Delete(call);
1441      Delete(target);
1442
1443      if (make_set_wrapper) {
1444	Setattr(n, "sym:name", mrename_set);
1445	functionWrapper(n);
1446      } else {
1447	SetFlag(n, "feature:immutable");
1448      }
1449      /* Restore parameters */
1450      Setattr(n, "type", type);
1451      Setattr(n, "name", name);
1452      Setattr(n, "sym:name", symname);
1453
1454      /* Delete all attached typemaps and typemap attributes */
1455      Iterator ki;
1456      for (ki = First(n); ki.key; ki = Next(ki)) {
1457	if (Strncmp(ki.key, "tmap:", 5) == 0)
1458	  Delattr(n, ki.key);
1459      }
1460    }
1461    /* Emit get function */
1462    {
1463      int flags = Extend | SmartPointer | use_naturalvar_mode(n);
1464      if (is_non_virtual_protected_access(n))
1465        flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
1466      Swig_MembergetToFunction(n, ClassType, flags);
1467      Setattr(n, "sym:name", mrename_get);
1468      Setattr(n, "memberget", "1");
1469      functionWrapper(n);
1470    }
1471    Delete(mrename_get);
1472    Delete(mrename_set);
1473
1474  } else {
1475
1476    /* This code is used to support the attributefunction directive
1477       where member variables are converted automagically to
1478       accessor functions */
1479
1480#if 0
1481    Parm *p;
1482    String *gname;
1483    SwigType *vty;
1484    p = NewParm(type, 0);
1485    gname = NewStringf(AttributeFunctionGet, symname);
1486    if (!Extend) {
1487      ActionFunc = Copy(Swig_cmemberget_call(name, type));
1488      cpp_member_func(Char(gname), Char(gname), type, 0);
1489      Delete(ActionFunc);
1490    } else {
1491      String *cname = Swig_name_get(name);
1492      cpp_member_func(Char(cname), Char(gname), type, 0);
1493      Delete(cname);
1494    }
1495    Delete(gname);
1496    if (!GetFlag(n, "feature:immutable")) {
1497      gname = NewStringf(AttributeFunctionSet, symname);
1498      vty = NewString("void");
1499      if (!Extend) {
1500	ActionFunc = Copy(Swig_cmemberset_call(name, type));
1501	cpp_member_func(Char(gname), Char(gname), vty, p);
1502	Delete(ActionFunc);
1503      } else {
1504	String *cname = Swig_name_set(name);
1505	cpp_member_func(Char(cname), Char(gname), vty, p);
1506	Delete(cname);
1507      }
1508      Delete(gname);
1509    }
1510    ActionFunc = 0;
1511#endif
1512  }
1513  Swig_restore(n);
1514  return SWIG_OK;
1515}
1516
1517/* ----------------------------------------------------------------------
1518 * Language::staticmembervariableHandler()
1519 * ---------------------------------------------------------------------- */
1520
1521int Language::staticmembervariableHandler(Node *n) {
1522  Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
1523  String *value = Getattr(n, "value");
1524  String *classname = !SmartPointer ? (is_non_virtual_protected_access(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase");
1525
1526  if (!value || !Getattr(n, "hasconsttype")) {
1527    String *name = Getattr(n, "name");
1528    String *symname = Getattr(n, "sym:name");
1529    String *cname, *mrename;
1530
1531    /* Create the variable name */
1532    mrename = Swig_name_member(ClassPrefix, symname);
1533    cname = NewStringf("%s::%s", classname, name);
1534
1535    Setattr(n, "sym:name", mrename);
1536    Setattr(n, "name", cname);
1537
1538    /* Wrap as an ordinary global variable */
1539    variableWrapper(n);
1540
1541    Delete(mrename);
1542    Delete(cname);
1543  } else {
1544
1545    /* This is a C++ static member declaration with an initializer and it's const.
1546       Certain C++ compilers optimize this out so that there is no linkage to a
1547       memory address.  Example:
1548
1549       class Foo {
1550       public:
1551         static const int x = 3;
1552       };
1553
1554       Some discussion of this in section 9.4 of the C++ draft standard.
1555
1556       Also, we have to manage the case:
1557
1558       class Foo {
1559       public:
1560       %extend {
1561         static const int x = 3;
1562       }
1563       };
1564
1565       in which there's no actual Foo::x variable to refer to. In this case,
1566       the best we can do is to wrap the given value verbatim.
1567     */
1568
1569
1570    String *name = Getattr(n, "name");
1571    String *cname = NewStringf("%s::%s", classname, name);
1572    if (Extend) {
1573      /* the variable is a synthesized one.
1574         There's nothing we can do; we just keep the given value */
1575    } else {
1576      /* we refer to the value as Foo::x */
1577      String *value = SwigType_namestr(cname);
1578      Setattr(n, "value", value);
1579    }
1580
1581    SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n, "type"));
1582    SwigType *t2 = SwigType_strip_qualifiers(t1);
1583    Setattr(n, "type", t2);
1584    Delete(t1);
1585    Delete(t2);
1586    SetFlag(n, "wrappedasconstant");
1587    memberconstantHandler(n);
1588    Delete(cname);
1589  }
1590
1591  Swig_restore(n);
1592  return SWIG_OK;
1593}
1594
1595
1596/* ----------------------------------------------------------------------
1597 * Language::externDeclaration()
1598 * ---------------------------------------------------------------------- */
1599
1600int Language::externDeclaration(Node *n) {
1601  return emit_children(n);
1602}
1603
1604/* ----------------------------------------------------------------------
1605 * Language::enumDeclaration()
1606 * ---------------------------------------------------------------------- */
1607
1608int Language::enumDeclaration(Node *n) {
1609  if (!ImportMode) {
1610    emit_children(n);
1611  }
1612  return SWIG_OK;
1613}
1614
1615/* ----------------------------------------------------------------------
1616 * Language::enumvalueDeclaration()
1617 * ---------------------------------------------------------------------- */
1618
1619int Language::enumvalueDeclaration(Node *n) {
1620  if (CurrentClass && (cplus_mode != PUBLIC))
1621    return SWIG_NOWRAP;
1622
1623  Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
1624  String *value = Getattr(n, "value");
1625  String *name = Getattr(n, "name");
1626  String *tmpValue;
1627
1628  if (value)
1629    tmpValue = NewString(value);
1630  else
1631    tmpValue = NewString(name);
1632  Setattr(n, "value", tmpValue);
1633
1634  if (!CurrentClass || !cparse_cplusplus) {
1635    Setattr(n, "name", tmpValue);	/* for wrapping of enums in a namespace when emit_action is used */
1636    constantWrapper(n);
1637  } else {
1638    memberconstantHandler(n);
1639  }
1640
1641  Delete(tmpValue);
1642  Swig_restore(n);
1643  return SWIG_OK;
1644}
1645
1646/* ----------------------------------------------------------------------
1647 * Language::enumforwardDeclaration()
1648 * ---------------------------------------------------------------------- */
1649
1650int Language::enumforwardDeclaration(Node *n) {
1651  (void) n;
1652  return SWIG_OK;
1653}
1654
1655/* -----------------------------------------------------------------------------
1656 * Language::memberconstantHandler()
1657 * ----------------------------------------------------------------------------- */
1658
1659int Language::memberconstantHandler(Node *n) {
1660
1661  Swig_require("memberconstantHandler", n, "*name", "*sym:name", "value", NIL);
1662
1663  if (!GetFlag(n, "feature:allowexcept")) {
1664    UnsetFlag(n, "feature:except");
1665  }
1666  if (Getattr(n, "feature:exceptvar")) {
1667    Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
1668  }
1669
1670  String *name = Getattr(n, "name");
1671  String *symname = Getattr(n, "sym:name");
1672  String *value = Getattr(n, "value");
1673
1674  String *mrename = Swig_name_member(ClassPrefix, symname);
1675  Setattr(n, "sym:name", mrename);
1676
1677  String *new_name = 0;
1678  if (Extend)
1679    new_name = Copy(value);
1680  else
1681    new_name = NewStringf("%s::%s", is_non_virtual_protected_access(n) ? DirectorClassName : ClassName, name);
1682  Setattr(n, "name", new_name);
1683
1684  constantWrapper(n);
1685  Delete(mrename);
1686  Delete(new_name);
1687  Swig_restore(n);
1688  return SWIG_OK;
1689}
1690
1691/* ----------------------------------------------------------------------
1692 * Language::typedefHandler()
1693 * ---------------------------------------------------------------------- */
1694
1695int Language::typedefHandler(Node *n) {
1696  /* since this is a recurring issue, we are going to remember the
1697     typedef pointer, if already it is not a pointer or reference, as
1698     in
1699
1700     typedef void NT;
1701     int func(NT *p);
1702
1703     see director_basic.i for example.
1704   */
1705  SwigType *name = Getattr(n, "name");
1706  SwigType *decl = Getattr(n, "decl");
1707  if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
1708    SwigType *pname = Copy(name);
1709    SwigType_add_pointer(pname);
1710    SwigType_remember(pname);
1711    Delete(pname);
1712  }
1713  return SWIG_OK;
1714}
1715
1716/* ----------------------------------------------------------------------
1717 * Language::classDirectorMethod()
1718 * ---------------------------------------------------------------------- */
1719
1720int Language::classDirectorMethod(Node *n, Node *parent, String *super) {
1721  (void) n;
1722  (void) parent;
1723  (void) super;
1724  return SWIG_OK;
1725}
1726
1727/* ----------------------------------------------------------------------
1728 * Language::classDirectorConstructor()
1729 * ---------------------------------------------------------------------- */
1730
1731int Language::classDirectorConstructor(Node *n) {
1732  (void) n;
1733  return SWIG_OK;
1734}
1735
1736/* ----------------------------------------------------------------------
1737 * Language::classDirectorDefaultConstructor()
1738 * ---------------------------------------------------------------------- */
1739
1740int Language::classDirectorDefaultConstructor(Node *n) {
1741  (void) n;
1742  return SWIG_OK;
1743}
1744
1745static String *vtable_method_id(Node *n) {
1746  String *nodeType = Getattr(n, "nodeType");
1747  int is_destructor = (Cmp(nodeType, "destructor") == 0);
1748  if (is_destructor)
1749    return 0;
1750  String *name = Getattr(n, "name");
1751  String *decl = Getattr(n, "decl");
1752  String *local_decl = SwigType_typedef_resolve_all(decl);
1753  String *tmp = SwigType_pop_function(local_decl);
1754  Delete(local_decl);
1755  local_decl = tmp;
1756  Node *method_id = NewStringf("%s|%s", name, local_decl);
1757  Delete(local_decl);
1758  return method_id;
1759}
1760
1761
1762/* ----------------------------------------------------------------------
1763 * Language::unrollVirtualMethods()
1764 * ---------------------------------------------------------------------- */
1765int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase) {
1766  Node *ni;
1767  String *nodeType;
1768  String *classname;
1769  String *decl;
1770  bool first_base = false;
1771  // recurse through all base classes to build the vtable
1772  List *bl = Getattr(n, "bases");
1773  if (bl) {
1774    Iterator bi;
1775    for (bi = First(bl); bi.item; bi = Next(bi)) {
1776      if (first_base && !director_multiple_inheritance)
1777	break;
1778      unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
1779      first_base = true;
1780    }
1781  }
1782  // recurse through all protected base classes to build the vtable, as needed
1783  bl = Getattr(n, "protectedbases");
1784  if (bl) {
1785    Iterator bi;
1786    for (bi = First(bl); bi.item; bi = Next(bi)) {
1787      if (first_base && !director_multiple_inheritance)
1788	break;
1789      unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
1790      first_base = true;
1791    }
1792  }
1793  // find the methods that need directors
1794  classname = Getattr(n, "name");
1795  for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
1796    /* we only need to check the virtual members */
1797    if (!checkAttribute(ni, "storage", "virtual"))
1798      continue;
1799    nodeType = Getattr(ni, "nodeType");
1800    /* we need to add methods(cdecl) and destructor (to check for throw decl) */
1801    int is_destructor = (Cmp(nodeType, "destructor") == 0);
1802    if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
1803      decl = Getattr(ni, "decl");
1804      /* extra check for function type and proper access */
1805      if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(ni)) || need_nonpublic_member(ni))) {
1806	String *name = Getattr(ni, "name");
1807	Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(ni);
1808	/* Make sure that the new method overwrites the existing: */
1809	int len = Len(vm);
1810	const int DO_NOT_REPLACE = -1;
1811	int replace = DO_NOT_REPLACE;
1812	for (int i = 0; i < len; i++) {
1813	  Node *item = Getitem(vm, i);
1814	  String *check_vmid = Getattr(item, "vmid");
1815
1816	  if (Strcmp(method_id, check_vmid) == 0) {
1817	    replace = i;
1818	    break;
1819	  }
1820	}
1821	/* filling a new method item */
1822	String *fqdname = NewStringf("%s::%s", classname, name);
1823	Hash *item = NewHash();
1824	Setattr(item, "fqdname", fqdname);
1825	Node *m = Copy(ni);
1826
1827	/* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
1828	SwigType *ty = NewString(Getattr(m, "type"));
1829	SwigType_push(ty, decl);
1830	if (SwigType_isqualifier(ty)) {
1831	  Delete(SwigType_pop(ty));
1832	}
1833	Delete(SwigType_pop_function(ty));
1834	Setattr(m, "returntype", ty);
1835
1836	String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
1837	/* apply the features of the original method found in the base class */
1838	Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
1839	Setattr(item, "methodNode", m);
1840	Setattr(item, "vmid", method_id);
1841	if (replace == DO_NOT_REPLACE)
1842	  Append(vm, item);
1843	else
1844	  Setitem(vm, replace, item);
1845
1846	Delete(mname);
1847      }
1848      if (is_destructor) {
1849	virtual_destructor = 1;
1850      }
1851    }
1852  }
1853
1854  /*
1855     We delete all the nodirector methods. This prevents the
1856     generation of 'empty' director classes.
1857
1858     But this has to be done outside the previous 'for'
1859     an the recursive loop!.
1860   */
1861  if (n == parent) {
1862    int len = Len(vm);
1863    for (int i = 0; i < len; i++) {
1864      Node *item = Getitem(vm, i);
1865      Node *m = Getattr(item, "methodNode");
1866      /* retrieve the director features */
1867      int mdir = GetFlag(m, "feature:director");
1868      int mndir = GetFlag(m, "feature:nodirector");
1869      /* 'nodirector' has precedence over 'director' */
1870      int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
1871      /* check if the method was found only in a base class */
1872      Node *p = Getattr(m, "parentNode");
1873      if (p != n) {
1874	Node *c = Copy(m);
1875	Setattr(c, "parentNode", n);
1876	int cdir = GetFlag(c, "feature:director");
1877	int cndir = GetFlag(c, "feature:nodirector");
1878	dir = (cdir || cndir) ? (cdir && !cndir) : dir;
1879	Delete(c);
1880      }
1881      if (dir) {
1882	/* be sure the 'nodirector' feature is disabled  */
1883	if (mndir)
1884	  Delattr(m, "feature:nodirector");
1885      } else {
1886	/* or just delete from the vm, since is not a director method */
1887	Delitem(vm, i);
1888	len--;
1889	i--;
1890      }
1891    }
1892  }
1893
1894  return SWIG_OK;
1895}
1896
1897
1898/* ----------------------------------------------------------------------
1899 * Language::classDirectorDisown()
1900 * ---------------------------------------------------------------------- */
1901
1902int Language::classDirectorDisown(Node *n) {
1903  Node *disown = NewHash();
1904  String *mrename;
1905  String *symname = Getattr(n, "sym:name");
1906  mrename = Swig_name_disown(symname);	//Getattr(n, "name"));
1907  String *type = NewString(ClassType);
1908  String *name = NewString("self");
1909  SwigType_add_pointer(type);
1910  Parm *p = NewParm(type, name);
1911  Delete(name);
1912  Delete(type);
1913  type = NewString("void");
1914  String *action = NewString("");
1915  Printv(action, "{\n", "Swig::Director *director = dynamic_cast<Swig::Director *>(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL);
1916  Setattr(disown, "wrap:action", action);
1917  Setattr(disown, "name", mrename);
1918  Setattr(disown, "sym:name", mrename);
1919  Setattr(disown, "type", type);
1920  Setattr(disown, "parms", p);
1921  Delete(action);
1922  Delete(mrename);
1923  Delete(type);
1924  Delete(p);
1925
1926  functionWrapper(disown);
1927  Delete(disown);
1928  return SWIG_OK;
1929}
1930
1931/* ----------------------------------------------------------------------
1932 * Language::classDirectorConstructors()
1933 * ---------------------------------------------------------------------- */
1934
1935int Language::classDirectorConstructors(Node *n) {
1936  Node *ni;
1937  String *nodeType;
1938  Node *parent = Swig_methodclass(n);
1939  int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0;
1940  int protected_ctor = 0;
1941  int constructor = 0;
1942
1943  /* emit constructors */
1944  for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
1945    nodeType = Getattr(ni, "nodeType");
1946    if (Cmp(nodeType, "constructor") == 0) {
1947      Parm *parms = Getattr(ni, "parms");
1948      if (is_public(ni)) {
1949	/* emit public constructor */
1950	classDirectorConstructor(ni);
1951	constructor = 1;
1952	if (default_ctor)
1953	  default_ctor = !ParmList_numrequired(parms);
1954      } else {
1955	/* emit protected constructor if needed */
1956	if (need_nonpublic_ctor(ni)) {
1957	  classDirectorConstructor(ni);
1958	  constructor = 1;
1959	  protected_ctor = 1;
1960	  if (default_ctor)
1961	    default_ctor = !ParmList_numrequired(parms);
1962	}
1963      }
1964    }
1965  }
1966  /* emit default constructor if needed */
1967  if (!constructor) {
1968    if (!default_ctor) {
1969      /* we get here because the class has no public, protected or
1970         default constructor, therefore, the director class can't be
1971         created, ie, is kind of abstract. */
1972      Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), "Director class '%s' can't be constructed\n", SwigType_namestr(Getattr(n, "name")));
1973      return SWIG_OK;
1974    }
1975    classDirectorDefaultConstructor(n);
1976    default_ctor = 1;
1977  }
1978  /* this is just to support old java behavior, ie, the default
1979     constructor is always emitted, even when protected, and not
1980     needed, since there is a public constructor already defined.
1981
1982     (scottm) This code is needed here to make the director_abstract +
1983     test generate compileable code (Example2 in director_abastract.i).
1984
1985     (mmatus) This is very strange, since swig compiled with gcc3.2.3
1986     doesn't need it here....
1987   */
1988  if (!default_ctor && !protected_ctor) {
1989    if (Getattr(parent, "allocate:default_base_constructor")) {
1990      classDirectorDefaultConstructor(n);
1991    }
1992  }
1993
1994  return SWIG_OK;
1995}
1996
1997/* ----------------------------------------------------------------------
1998 * Language::classDirectorMethods()
1999 * ---------------------------------------------------------------------- */
2000
2001int Language::classDirectorMethods(Node *n) {
2002  Node *vtable = Getattr(n, "vtable");
2003
2004  int len = Len(vtable);
2005  for (int i = 0; i < len; i++) {
2006    Node *item = Getitem(vtable, i);
2007    String *method = Getattr(item, "methodNode");
2008    String *fqdname = Getattr(item, "fqdname");
2009    if (GetFlag(method, "feature:nodirector"))
2010      continue;
2011
2012    String *type = Getattr(method, "nodeType");
2013    if (!Cmp(type, "destructor")) {
2014      classDirectorDestructor(method);
2015    } else {
2016      if (classDirectorMethod(method, n, fqdname) == SWIG_OK) {
2017	Setattr(item, "director", "1");
2018      }
2019    }
2020  }
2021
2022  return SWIG_OK;
2023}
2024
2025/* ----------------------------------------------------------------------
2026 * Language::classDirectorInit()
2027 * ---------------------------------------------------------------------- */
2028
2029int Language::classDirectorInit(Node *n) {
2030  (void) n;
2031  return SWIG_OK;
2032}
2033
2034/* ----------------------------------------------------------------------
2035 * Language::classDirectorDestructor()
2036 * ---------------------------------------------------------------------- */
2037
2038int Language::classDirectorDestructor(Node *n) {
2039  /*
2040     Always emit the virtual destructor in the declaration and in the
2041     compilation unit.  Been explicit here can't make any damage, and
2042     can solve some nasty C++ compiler problems.
2043   */
2044  File *f_directors = Swig_filebyname("director");
2045  File *f_directors_h = Swig_filebyname("director_h");
2046  if (Getattr(n, "throw")) {
2047    Printf(f_directors_h, "    virtual ~%s() throw ();\n", DirectorClassName);
2048    Printf(f_directors, "%s::~%s() throw () {\n}\n\n", DirectorClassName, DirectorClassName);
2049  } else {
2050    Printf(f_directors_h, "    virtual ~%s();\n", DirectorClassName);
2051    Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
2052  }
2053  return SWIG_OK;
2054}
2055
2056/* ----------------------------------------------------------------------
2057 * Language::classDirectorEnd()
2058 * ---------------------------------------------------------------------- */
2059
2060int Language::classDirectorEnd(Node *n) {
2061  (void) n;
2062  return SWIG_OK;
2063}
2064
2065/* ----------------------------------------------------------------------
2066 * Language::classDirector()
2067 * ---------------------------------------------------------------------- */
2068
2069int Language::classDirector(Node *n) {
2070  Node *module = Getattr(n, "module");
2071  String *classtype = Getattr(n, "classtype");
2072  Hash *directormap = 0;
2073  if (module) {
2074    directormap = Getattr(module, "wrap:directormap");
2075    if (directormap == 0) {
2076      directormap = NewHash();
2077      Setattr(module, "wrap:directormap", directormap);
2078    }
2079  }
2080  List *vtable = NewList();
2081  int virtual_destructor = 0;
2082  unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
2083
2084  // Emit all the using base::member statements for non virtual members (allprotected mode)
2085  Node *ni;
2086  String *using_protected_members_code = NewString("");
2087  for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
2088    Node *nodeType = Getattr(ni, "nodeType");
2089    bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
2090    if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
2091      if (is_non_virtual_protected_access(ni)) {
2092        Node *overloaded = Getattr(ni, "sym:overloaded");
2093        // emit the using base::member statement (but only once if the method is overloaded)
2094        if (!overloaded || (overloaded && (overloaded == ni)))
2095          Printf(using_protected_members_code, "    using %s::%s;\n", SwigType_namestr(ClassName), Getattr(ni, "name"));
2096      }
2097    }
2098  }
2099
2100  if (virtual_destructor || Len(vtable) > 0) {
2101    if (!virtual_destructor) {
2102      String *classtype = Getattr(n, "classtype");
2103      Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype);
2104    }
2105
2106    Setattr(n, "vtable", vtable);
2107    if (directormap != 0) {
2108      Setattr(directormap, classtype, n);
2109    }
2110    classDirectorInit(n);
2111    classDirectorConstructors(n);
2112    classDirectorMethods(n);
2113
2114    File *f_directors_h = Swig_filebyname("director_h");
2115    Printv(f_directors_h, using_protected_members_code, NIL);
2116
2117    classDirectorEnd(n);
2118  }
2119  Delete(vtable);
2120  Delete(using_protected_members_code);
2121  return SWIG_OK;
2122}
2123
2124/* ----------------------------------------------------------------------
2125 * Language::classDeclaration()
2126 * ---------------------------------------------------------------------- */
2127
2128static void addCopyConstructor(Node *n) {
2129  Node *cn = NewHash();
2130  set_nodeType(cn, "constructor");
2131  Setattr(cn, "access", "public");
2132  Setfile(cn, Getfile(n));
2133  Setline(cn, Getline(n));
2134
2135  String *cname = Getattr(n, "name");
2136  SwigType *type = Copy(cname);
2137  String *last = Swig_scopename_last(cname);
2138  String *name = NewStringf("%s::%s", cname, last);
2139  String *cc = NewStringf("r.q(const).%s", type);
2140  String *decl = NewStringf("f(%s).", cc);
2141  String *csymname = Getattr(n, "sym:name");
2142  String *oldname = csymname;
2143
2144  if (Getattr(n, "allocate:has_constructor")) {
2145    // to work properly with '%rename Class', we must look
2146    // for any other constructor in the class, which has not been
2147    // renamed, and use its name as oldname.
2148    Node *c;
2149    for (c = firstChild(n); c; c = nextSibling(c)) {
2150      const char *tag = Char(nodeType(c));
2151      if (strcmp(tag, "constructor") == 0) {
2152	String *cname = Getattr(c, "name");
2153	String *csname = Getattr(c, "sym:name");
2154	String *clast = Swig_scopename_last(cname);
2155	if (Equal(csname, clast)) {
2156	  oldname = csname;
2157	  break;
2158	}
2159      }
2160    }
2161  }
2162
2163  String *symname = Swig_name_make(cn, cname, last, decl, oldname);
2164  if (Strcmp(symname, "$ignore") != 0) {
2165    if (!symname) {
2166      symname = Copy(csymname);
2167    }
2168    Parm *p = NewParm(cc, "other");
2169
2170    Setattr(cn, "name", name);
2171    Setattr(cn, "sym:name", symname);
2172    SetFlag(cn, "feature:new");
2173    Setattr(cn, "decl", decl);
2174    Setattr(cn, "parentNode", n);
2175    Setattr(cn, "parms", p);
2176    Setattr(cn, "copy_constructor", "1");
2177
2178    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
2179    Node *on = Swig_symbol_add(symname, cn);
2180    Swig_symbol_setscope(oldscope);
2181    Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
2182
2183    if (on == cn) {
2184      Node *access = NewHash();
2185      set_nodeType(access, "access");
2186      Setattr(access, "kind", "public");
2187      appendChild(n, access);
2188      appendChild(n, cn);
2189      Setattr(n, "has_copy_constructor", "1");
2190      Setattr(n, "copy_constructor_decl", decl);
2191      Setattr(n, "allocate:copy_constructor", "1");
2192      Delete(access);
2193    }
2194  }
2195  Delete(cn);
2196  Delete(last);
2197  Delete(name);
2198  Delete(decl);
2199  Delete(symname);
2200}
2201
2202static void addDefaultConstructor(Node *n) {
2203  Node *cn = NewHash();
2204  set_nodeType(cn, "constructor");
2205  Setattr(cn, "access", "public");
2206  Setfile(cn, Getfile(n));
2207  Setline(cn, Getline(n));
2208
2209  String *cname = Getattr(n, "name");
2210  String *last = Swig_scopename_last(cname);
2211  String *name = NewStringf("%s::%s", cname, last);
2212  String *decl = NewString("f().");
2213  String *csymname = Getattr(n, "sym:name");
2214  String *oldname = csymname;
2215  String *symname = Swig_name_make(cn, cname, last, decl, oldname);
2216  if (Strcmp(symname, "$ignore") != 0) {
2217    if (!symname) {
2218      symname = Copy(csymname);
2219    }
2220
2221    Setattr(cn, "name", name);
2222    Setattr(cn, "sym:name", symname);
2223    SetFlag(cn, "feature:new");
2224    Setattr(cn, "decl", decl);
2225    Setattr(cn, "parentNode", n);
2226    Setattr(cn, "default_constructor", "1");
2227
2228    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
2229    Node *on = Swig_symbol_add(symname, cn);
2230    Swig_symbol_setscope(oldscope);
2231    Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
2232
2233    if (on == cn) {
2234      Node *access = NewHash();
2235      set_nodeType(access, "access");
2236      Setattr(access, "kind", "public");
2237      appendChild(n, access);
2238      appendChild(n, cn);
2239      Setattr(n, "has_default_constructor", "1");
2240      Setattr(n, "allocate:default_constructor", "1");
2241      Delete(access);
2242    }
2243  }
2244  Delete(cn);
2245  Delete(last);
2246  Delete(name);
2247  Delete(decl);
2248  Delete(symname);
2249}
2250
2251static void addDestructor(Node *n) {
2252  Node *cn = NewHash();
2253  set_nodeType(cn, "destructor");
2254  Setattr(cn, "access", "public");
2255  Setfile(cn, Getfile(n));
2256  Setline(cn, Getline(n));
2257
2258  String *cname = Getattr(n, "name");
2259  String *last = Swig_scopename_last(cname);
2260  Insert(last, 0, "~");
2261  String *name = NewStringf("%s::%s", cname, last);
2262  String *decl = NewString("f().");
2263  String *symname = Swig_name_make(cn, cname, last, decl, 0);
2264  if (Strcmp(symname, "$ignore") != 0) {
2265    if (!symname) {
2266      symname = NewStringf("~%s", Getattr(n, "sym:name"));
2267    }
2268
2269    Setattr(cn, "name", name);
2270    Setattr(cn, "sym:name", symname);
2271    Setattr(cn, "decl", "f().");
2272    Setattr(cn, "parentNode", n);
2273
2274    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
2275    Node *on = Swig_symbol_add(symname, cn);
2276    Swig_symbol_setscope(oldscope);
2277    Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
2278
2279    if (on == cn) {
2280      Node *access = NewHash();
2281      set_nodeType(access, "access");
2282      Setattr(access, "kind", "public");
2283      appendChild(n, access);
2284      appendChild(n, cn);
2285      Setattr(n, "has_destructor", "1");
2286      Setattr(n, "allocate:destructor", "1");
2287      Delete(access);
2288    }
2289  }
2290  Delete(cn);
2291  Delete(last);
2292  Delete(name);
2293  Delete(decl);
2294  Delete(symname);
2295}
2296
2297int Language::classDeclaration(Node *n) {
2298  String *ochildren = Getattr(n, "feature:onlychildren");
2299  if (ochildren) {
2300    Setattr(n, "feature:emitonlychildren", ochildren);
2301    emit_children(n);
2302    Delattr(n, "feature:emitonlychildren");
2303    SetFlag(n, "feature:ignore");
2304    return SWIG_NOWRAP;
2305  }
2306
2307  String *kind = Getattr(n, "kind");
2308  String *name = Getattr(n, "name");
2309  String *tdname = Getattr(n, "tdname");
2310  String *symname = Getattr(n, "sym:name");
2311
2312  char *classname = tdname ? Char(tdname) : Char(name);
2313  char *iname = Char(symname);
2314  int strip = (tdname || CPlusPlus) ? 1 : 0;
2315
2316
2317  if (!classname) {
2318    Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
2319    return SWIG_NOWRAP;
2320  }
2321
2322  /* Check symbol name for template.   If not renamed. Issue a warning */
2323  if (!validIdentifier(symname)) {
2324    Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname));
2325    return SWIG_NOWRAP;
2326  }
2327
2328  Swig_save("classDeclaration", n, "name", NIL);
2329  Setattr(n, "name", classname);
2330
2331  if (Cmp(kind, "class") == 0) {
2332    cplus_mode = PRIVATE;
2333  } else {
2334    cplus_mode = PUBLIC;
2335  }
2336
2337  ClassName = NewString(classname);
2338  ClassPrefix = NewString(iname);
2339  if (strip) {
2340    ClassType = NewString(classname);
2341  } else {
2342    ClassType = NewStringf("%s %s", kind, classname);
2343  }
2344  Setattr(n, "classtypeobj", Copy(ClassType));
2345  Setattr(n, "classtype", SwigType_namestr(ClassType));
2346
2347  InClass = 1;
2348  CurrentClass = n;
2349
2350
2351  /* Call classHandler() here */
2352  if (!ImportMode) {
2353    int dir = 0;
2354    if (directorsEnabled()) {
2355      int ndir = GetFlag(n, "feature:director");
2356      int nndir = GetFlag(n, "feature:nodirector");
2357      /* 'nodirector' has precedence over 'director' */
2358      dir = (ndir || nndir) ? (ndir && !nndir) : 0;
2359    }
2360    int abstract = !dir && abstractClassTest(n);
2361    int odefault = (GenerateDefault && !GetFlag(n, "feature:nodefault"));
2362
2363    /* default constructor */
2364    if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) {
2365      if (!Getattr(n, "has_constructor") && !Getattr(n, "allocate:has_constructor") && (Getattr(n, "allocate:default_constructor"))) {
2366	addDefaultConstructor(n);
2367      }
2368    }
2369    /* copy constructor */
2370    if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) {
2371      if (!Getattr(n, "has_copy_constructor") && !Getattr(n, "allocate:has_copy_constructor")
2372	  && (Getattr(n, "allocate:copy_constructor"))
2373	  && (!GetFlag(n, "feature:ignore"))) {
2374	addCopyConstructor(n);
2375      }
2376    }
2377    /* default destructor */
2378    if (!GetFlag(n, "feature:nodefaultdtor") && odefault) {
2379      if (!Getattr(n, "has_destructor") && (!Getattr(n, "allocate:has_destructor"))
2380	  && (Getattr(n, "allocate:default_destructor"))
2381	  && (!GetFlag(n, "feature:ignore"))) {
2382	addDestructor(n);
2383      }
2384    }
2385
2386    if (dir) {
2387      DirectorClassName = NewStringf("SwigDirector_%s", symname);
2388      classDirector(n);
2389    }
2390    /* check for abstract after resolving directors */
2391    Abstract = abstractClassTest(n);
2392
2393    classHandler(n);
2394  } else {
2395    Abstract = abstractClassTest(n);
2396    Language::classHandler(n);
2397  }
2398
2399  InClass = 0;
2400  CurrentClass = 0;
2401  Delete(ClassType);
2402  ClassType = 0;
2403  Delete(ClassPrefix);
2404  ClassPrefix = 0;
2405  Delete(ClassName);
2406  ClassName = 0;
2407  Delete(DirectorClassName);
2408  DirectorClassName = 0;
2409  Swig_restore(n);
2410  return SWIG_OK;
2411}
2412
2413/* ----------------------------------------------------------------------
2414 * Language::classHandler()
2415 * ---------------------------------------------------------------------- */
2416
2417int Language::classHandler(Node *n) {
2418
2419  bool hasDirector = Swig_directorclass(n) ? true : false;
2420
2421  /* Emit all of the class members */
2422  emit_children(n);
2423
2424  /* Look for smart pointer handling */
2425  if (Getattr(n, "allocate:smartpointer")) {
2426    List *methods = Getattr(n, "allocate:smartpointer");
2427    cplus_mode = PUBLIC;
2428    SmartPointer = CWRAP_SMART_POINTER;
2429    Iterator c;
2430    for (c = First(methods); c.item; c = Next(c)) {
2431      emit_one(c.item);
2432    }
2433    SmartPointer = 0;
2434  }
2435
2436  cplus_mode = PUBLIC;
2437
2438  /* emit director disown method */
2439  if (hasDirector) {
2440    classDirectorDisown(n);
2441
2442    /* Emit additional protected virtual methods - only needed if the language module
2443     * codes logic in the C++ layer instead of the director proxy class method - primarily
2444     * to catch public use of protected methods by the scripting languages. */
2445    if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
2446      Node *vtable = Getattr(n, "vtable");
2447      String *symname = Getattr(n, "sym:name");
2448      AccessMode old_mode = cplus_mode;
2449      cplus_mode = PROTECTED;
2450      int len = Len(vtable);
2451      for (int i = 0; i < len; i++) {
2452	Node *item = Getitem(vtable, i);
2453	Node *method = Getattr(item, "methodNode");
2454	SwigType *type = Getattr(method, "nodeType");
2455	if (Strcmp(type, "cdecl") != 0)
2456	  continue;
2457	if (GetFlag(method, "feature:ignore"))
2458	  continue;
2459	String *methodname = Getattr(method, "sym:name");
2460	String *wrapname = NewStringf("%s_%s", symname, methodname);
2461	if (!Getattr(symbols, wrapname) && (!is_public(method))) {
2462	  Node *m = Copy(method);
2463	  Setattr(m, "director", "1");
2464	  Setattr(m, "parentNode", n);
2465	  /*
2466	   * There is a bug that needs fixing still...
2467	   * This area of code is creating methods which have not been overidden in a derived class (director methods that are protected in the base)
2468	   * If the method is overloaded, then Swig_overload_dispatch() incorrectly generates a call to the base wrapper, _wrap_xxx method
2469	   * See director_protected_overloaded.i - Possibly sym:overname needs correcting here.
2470	  Printf(stdout, "new method: %s::%s(%s)\n", Getattr(parentNode(m), "name"), Getattr(m, "name"), ParmList_str_defaultargs(Getattr(m, "parms")));
2471	  */
2472	  cDeclaration(m);
2473	  Delete(m);
2474	}
2475	Delete(wrapname);
2476      }
2477      cplus_mode = old_mode;
2478    }
2479  }
2480
2481  return SWIG_OK;
2482}
2483
2484/* ----------------------------------------------------------------------
2485 * Language::classforwardDeclaration()
2486 * ---------------------------------------------------------------------- */
2487
2488int Language::classforwardDeclaration(Node *n) {
2489  (void) n;
2490  return SWIG_OK;
2491}
2492
2493/* ----------------------------------------------------------------------
2494 * Language::constructorDeclaration()
2495 * ---------------------------------------------------------------------- */
2496
2497int Language::constructorDeclaration(Node *n) {
2498  String *name = Getattr(n, "name");
2499  String *symname = Getattr(n, "sym:name");
2500
2501  if (!symname)
2502    return SWIG_NOWRAP;
2503  if (!CurrentClass)
2504    return SWIG_NOWRAP;
2505  if (ImportMode)
2506    return SWIG_NOWRAP;
2507
2508  if (Extend) {
2509    /* extend default constructor can be safely ignored if there is already one */
2510    int num_required = ParmList_numrequired(Getattr(n, "parms"));
2511    if ((num_required == 0) && Getattr(CurrentClass, "has_default_constructor")) {
2512      return SWIG_NOWRAP;
2513    }
2514    if ((num_required == 1) && Getattr(CurrentClass, "has_copy_constructor")) {
2515      String *ccdecl = Getattr(CurrentClass, "copy_constructor_decl");
2516      if (ccdecl && (Strcmp(ccdecl, Getattr(n, "decl")) == 0)) {
2517	return SWIG_NOWRAP;
2518      }
2519    }
2520  }
2521
2522  /* clean protected overloaded constructors, in case they are not needed anymore */
2523  Node *over = Swig_symbol_isoverloaded(n);
2524  if (over && !Getattr(CurrentClass, "sym:cleanconstructor")) {
2525    int dirclass = Swig_directorclass(CurrentClass);
2526    Node *nn = over;
2527    while (nn) {
2528      if (!is_public(nn)) {
2529	if (!dirclass || !need_nonpublic_ctor(nn)) {
2530	  SetFlag(nn, "feature:ignore");
2531	}
2532      }
2533      nn = Getattr(nn, "sym:nextSibling");
2534    }
2535    clean_overloaded(over);
2536    Setattr(CurrentClass, "sym:cleanconstructor", "1");
2537  }
2538
2539  if ((cplus_mode != PUBLIC)) {
2540    /* check only for director classes */
2541    if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n))
2542      return SWIG_NOWRAP;
2543  }
2544
2545  /* Name adjustment for %name */
2546  Swig_save("constructorDeclaration", n, "sym:name", NIL);
2547
2548  {
2549    String *base = Swig_scopename_last(name);
2550    if ((Strcmp(base, symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) {
2551      Setattr(n, "sym:name", ClassPrefix);
2552    }
2553    Delete(base);
2554  }
2555
2556  /* Only create a constructor if the class is not abstract */
2557  if (!Abstract) {
2558    Node *over;
2559    over = Swig_symbol_isoverloaded(n);
2560    if (over)
2561      over = first_nontemplate(over);
2562    if ((over) && (!overloading)) {
2563      /* If the symbol is overloaded.  We check to see if it is a copy constructor.  If so,
2564         we invoke copyconstructorHandler() as a special case. */
2565      if (Getattr(n, "copy_constructor") && (!Getattr(CurrentClass, "has_copy_constructor"))) {
2566	copyconstructorHandler(n);
2567	Setattr(CurrentClass, "has_copy_constructor", "1");
2568      } else {
2569	if (Getattr(over, "copy_constructor"))
2570	  over = Getattr(over, "sym:nextSibling");
2571	if (over != n) {
2572	  Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number,
2573		       "Overloaded constructor ignored.  %s\n", Swig_name_decl(n));
2574	  Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over),
2575		       "Previous declaration is %s\n", Swig_name_decl(over));
2576	} else {
2577	  constructorHandler(n);
2578	}
2579      }
2580    } else {
2581      if (name && (Cmp(Swig_scopename_last(name), Swig_scopename_last(ClassName))) && !(Getattr(n, "template"))) {
2582	Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type.\n", SwigType_namestr(name));
2583	Swig_restore(n);
2584	return SWIG_NOWRAP;
2585      }
2586      constructorHandler(n);
2587    }
2588  }
2589  Setattr(CurrentClass, "has_constructor", "1");
2590
2591  Swig_restore(n);
2592  return SWIG_OK;
2593}
2594
2595/* ----------------------------------------------------------------------
2596 * get_director_ctor_code()
2597 * ---------------------------------------------------------------------- */
2598
2599static String *get_director_ctor_code(Node *n, String *director_ctor_code, String *director_prot_ctor_code, List *&abstract) {
2600  String *director_ctor = director_ctor_code;
2601  int use_director = Swig_directorclass(n);
2602  if (use_director) {
2603    Node *pn = Swig_methodclass(n);
2604    abstract = Getattr(pn, "abstract");
2605    if (director_prot_ctor_code) {
2606      int is_notabstract = GetFlag(pn, "feature:notabstract");
2607      int is_abstract = abstract && !is_notabstract;
2608      if (is_protected(n) || is_abstract) {
2609	director_ctor = director_prot_ctor_code;
2610	Delattr(pn, "abstract");
2611      } else {
2612	if (is_notabstract) {
2613	  Delattr(pn, "abstract");
2614	} else {
2615	  abstract = 0;
2616	}
2617      }
2618    }
2619  }
2620  return director_ctor;
2621}
2622
2623
2624/* ----------------------------------------------------------------------
2625 * Language::constructorHandler()
2626 * ---------------------------------------------------------------------- */
2627
2628int Language::constructorHandler(Node *n) {
2629  Swig_require("constructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
2630  String *symname = Getattr(n, "sym:name");
2631  String *mrename = Swig_name_construct(symname);
2632  String *nodeType = Getattr(n, "nodeType");
2633  int constructor = (!Cmp(nodeType, "constructor"));
2634  List *abstract = 0;
2635  String *director_ctor = get_director_ctor_code(n, director_ctor_code,
2636						 director_prot_ctor_code,
2637						 abstract);
2638  if (!constructor) {
2639    /* if not originally a constructor, still handle it as one */
2640    Setattr(n, "handled_as_constructor", "1");
2641  }
2642
2643  Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
2644  Setattr(n, "sym:name", mrename);
2645  functionWrapper(n);
2646  Delete(mrename);
2647  Swig_restore(n);
2648  if (abstract)
2649    Setattr(Swig_methodclass(n), "abstract", abstract);
2650  return SWIG_OK;
2651}
2652
2653/* ----------------------------------------------------------------------
2654 * Language::copyconstructorHandler()
2655 * ---------------------------------------------------------------------- */
2656
2657int Language::copyconstructorHandler(Node *n) {
2658  Swig_require("copyconstructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
2659  String *symname = Getattr(n, "sym:name");
2660  String *mrename = Swig_name_copyconstructor(symname);
2661  List *abstract = 0;
2662  String *director_ctor = get_director_ctor_code(n, director_ctor_code,
2663						 director_prot_ctor_code,
2664						 abstract);
2665  Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
2666  Setattr(n, "sym:name", mrename);
2667  functionWrapper(n);
2668  Delete(mrename);
2669  Swig_restore(n);
2670  if (abstract)
2671    Setattr(Swig_methodclass(n), "abstract", abstract);
2672  return SWIG_OK;
2673}
2674
2675/* ----------------------------------------------------------------------
2676 * Language::destructorDeclaration()
2677 * ---------------------------------------------------------------------- */
2678
2679int Language::destructorDeclaration(Node *n) {
2680
2681  if (!CurrentClass)
2682    return SWIG_NOWRAP;
2683  if (cplus_mode != PUBLIC)
2684    return SWIG_NOWRAP;
2685  if (ImportMode)
2686    return SWIG_NOWRAP;
2687
2688  if (Extend) {
2689    /* extend destructor can be safetly ignored if there is already one */
2690    if (Getattr(CurrentClass, "has_destructor")) {
2691      return SWIG_NOWRAP;
2692    }
2693  }
2694
2695  Swig_save("destructorDeclaration", n, "name", "sym:name", NIL);
2696
2697  char *c = GetChar(n, "name");
2698  if (c && (*c == '~'))
2699    Setattr(n, "name", c + 1);
2700
2701  c = GetChar(n, "sym:name");
2702  if (c && (*c == '~'))
2703    Setattr(n, "sym:name", c + 1);
2704
2705  /* Name adjustment for %name */
2706
2707  String *name = Getattr(n, "name");
2708  String *symname = Getattr(n, "sym:name");
2709
2710  if ((Strcmp(name, symname) == 0) || (Strcmp(symname, ClassPrefix) != 0)) {
2711    Setattr(n, "sym:name", ClassPrefix);
2712  }
2713
2714  destructorHandler(n);
2715
2716  Setattr(CurrentClass, "has_destructor", "1");
2717  Swig_restore(n);
2718  return SWIG_OK;
2719}
2720
2721/* ----------------------------------------------------------------------
2722 * Language::destructorHandler()
2723 * ---------------------------------------------------------------------- */
2724
2725int Language::destructorHandler(Node *n) {
2726  Swig_require("destructorHandler", n, "?name", "*sym:name", NIL);
2727  Swig_save("destructorHandler", n, "type", "parms", NIL);
2728
2729  String *symname = Getattr(n, "sym:name");
2730  String *mrename;
2731  char *csymname = Char(symname);
2732  if (csymname && (*csymname == '~'))
2733    csymname += 1;
2734
2735  mrename = Swig_name_destroy(csymname);
2736
2737  Swig_DestructorToFunction(n, ClassType, CPlusPlus, Extend);
2738  Setattr(n, "sym:name", mrename);
2739  functionWrapper(n);
2740  Delete(mrename);
2741  Swig_restore(n);
2742  return SWIG_OK;
2743}
2744
2745/* ----------------------------------------------------------------------
2746 * Language::accessDeclaration()
2747 * ---------------------------------------------------------------------- */
2748
2749int Language::accessDeclaration(Node *n) {
2750  String *kind = Getattr(n, "kind");
2751  if (Cmp(kind, "public") == 0) {
2752    cplus_mode = PUBLIC;
2753  } else if (Cmp(kind, "private") == 0) {
2754    cplus_mode = PRIVATE;
2755  } else if (Cmp(kind, "protected") == 0) {
2756    cplus_mode = PROTECTED;
2757  }
2758  return SWIG_OK;
2759}
2760
2761/* -----------------------------------------------------------------------------
2762 * Language::namespaceDeclaration()
2763 * ----------------------------------------------------------------------------- */
2764
2765int Language::namespaceDeclaration(Node *n) {
2766  if (Getattr(n, "alias"))
2767    return SWIG_OK;
2768  if (Getattr(n, "unnamed"))
2769    return SWIG_OK;
2770  emit_children(n);
2771  return SWIG_OK;
2772}
2773
2774int Language::validIdentifier(String *s) {
2775  char *c = Char(s);
2776  while (*c) {
2777    if (!(isalnum(*c) || (*c == '_')))
2778      return 0;
2779    c++;
2780  }
2781  return 1;
2782}
2783
2784/* -----------------------------------------------------------------------------
2785 * Language::usingDeclaration()
2786 * ----------------------------------------------------------------------------- */
2787
2788int Language::usingDeclaration(Node *n) {
2789  if (cplus_mode == PUBLIC) {
2790    Node *np = Copy(n);
2791    Node *c;
2792    for (c = firstChild(np); c; c = nextSibling(c)) {
2793      /* it seems for some cases this is needed, like A* A::boo() */
2794      if (CurrentClass)
2795	Setattr(c, "parentNode", CurrentClass);
2796      emit_one(c);
2797    }
2798    Delete(np);
2799  }
2800  return SWIG_OK;
2801}
2802
2803/* Stubs. Language modules need to implement these */
2804
2805/* ----------------------------------------------------------------------
2806 * Language::constantWrapper()
2807 * ---------------------------------------------------------------------- */
2808
2809int Language::constantWrapper(Node *n) {
2810  String *name = Getattr(n, "sym:name");
2811  SwigType *type = Getattr(n, "type");
2812  String *value = Getattr(n, "value");
2813  String *str = SwigType_str(type, name);
2814  Printf(stdout, "constantWrapper   : %s = %s\n", str, value);
2815  Delete(str);
2816  return SWIG_OK;
2817}
2818
2819/* ----------------------------------------------------------------------
2820 * Language::variableWrapper()
2821 * ---------------------------------------------------------------------- */
2822
2823int Language::variableWrapper(Node *n) {
2824  Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", NIL);
2825  String *symname = Getattr(n, "sym:name");
2826  SwigType *type = Getattr(n, "type");
2827  String *name = Getattr(n, "name");
2828
2829  /* If no way to set variables.  We simply create functions */
2830  int assignable = is_assignable(n);
2831  int flags = use_naturalvar_mode(n);
2832  if (!GetFlag(n, "wrappedasconstant"))
2833    flags = flags | Extend;
2834
2835  if (assignable) {
2836    int make_set_wrapper = 1;
2837    String *tm = Swig_typemap_lookup("globalin", n, name, 0);
2838
2839    Swig_VarsetToFunction(n, flags);
2840    String *sname = Swig_name_set(symname);
2841    Setattr(n, "sym:name", sname);
2842    Delete(sname);
2843
2844    if (!tm) {
2845      if (SwigType_isarray(type)) {
2846	Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
2847	make_set_wrapper = 0;
2848      }
2849    } else {
2850      String *pname0 = Swig_cparm_name(0, 0);
2851      Replace(tm, "$source", pname0, DOH_REPLACE_ANY);
2852      Replace(tm, "$target", name, DOH_REPLACE_ANY);
2853      Replace(tm, "$input", pname0, DOH_REPLACE_ANY);
2854      Setattr(n, "wrap:action", tm);
2855      Delete(tm);
2856      Delete(pname0);
2857    }
2858    if (make_set_wrapper) {
2859      functionWrapper(n);
2860    }
2861    /* Restore parameters */
2862    Setattr(n, "sym:name", symname);
2863    Setattr(n, "type", type);
2864    Setattr(n, "name", name);
2865
2866    /* Delete all attached typemaps and typemap attributes */
2867    Iterator ki;
2868    for (ki = First(n); ki.key; ki = Next(ki)) {
2869      if (Strncmp(ki.key, "tmap:", 5) == 0)
2870	Delattr(n, ki.key);
2871    }
2872  }
2873
2874  Swig_VargetToFunction(n, flags);
2875  String *gname = Swig_name_get(symname);
2876  Setattr(n, "sym:name", gname);
2877  Delete(gname);
2878  functionWrapper(n);
2879  Swig_restore(n);
2880  return SWIG_OK;
2881}
2882
2883/* ----------------------------------------------------------------------
2884 * Language::functionWrapper()
2885 * ---------------------------------------------------------------------- */
2886
2887int Language::functionWrapper(Node *n) {
2888  String *name = Getattr(n, "sym:name");
2889  SwigType *type = Getattr(n, "type");
2890  ParmList *parms = Getattr(n, "parms");
2891
2892  Printf(stdout, "functionWrapper   : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str_defaultargs(parms))));
2893  Printf(stdout, "           action : %s\n", Getattr(n, "wrap:action"));
2894  return SWIG_OK;
2895}
2896
2897/* -----------------------------------------------------------------------------
2898 * Language::nativeWrapper()
2899 * ----------------------------------------------------------------------------- */
2900
2901int Language::nativeWrapper(Node *n) {
2902  (void) n;
2903  return SWIG_OK;
2904}
2905
2906void Language::main(int argc, char *argv[]) {
2907  (void) argc;
2908  (void) argv;
2909}
2910
2911/* -----------------------------------------------------------------------------
2912 * Language::addSymbol()
2913 *
2914 * Adds a symbol entry.  Returns 1 if the symbol is added successfully.
2915 * Prints an error message and returns 0 if a conflict occurs.
2916 * ----------------------------------------------------------------------------- */
2917
2918int
2919Language::addSymbol(const String *s, const Node *n) {
2920  Node *c = Getattr(symbols, s);
2921  if (c && (c != n)) {
2922    Swig_error(input_file, line_number, "'%s' is multiply defined in the generated module.\n", s);
2923    Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s);
2924    return 0;
2925  }
2926  Setattr(symbols, s, n);
2927  return 1;
2928}
2929
2930/* -----------------------------------------------------------------------------
2931 * Language::symbolLookup()
2932 * ----------------------------------------------------------------------------- */
2933
2934Node *Language::symbolLookup(String *s) {
2935  return Getattr(symbols, s);
2936}
2937
2938/* -----------------------------------------------------------------------------
2939 * Language::classLookup()
2940 *
2941 * Tries to locate a class from a type definition
2942 * ----------------------------------------------------------------------------- */
2943
2944Node *Language::classLookup(SwigType *s) {
2945  Node *n = 0;
2946
2947  /* Look in hash of cached values */
2948  n = Getattr(classtypes, s);
2949  if (!n) {
2950    Symtab *stab = 0;
2951    SwigType *ty1 = SwigType_typedef_resolve_all(s);
2952    SwigType *ty2 = SwigType_strip_qualifiers(ty1);
2953    Delete(ty1);
2954    ty1 = 0;
2955
2956    String *base = SwigType_base(ty2);
2957
2958    Replaceall(base, "class ", "");
2959    Replaceall(base, "struct ", "");
2960    Replaceall(base, "union ", "");
2961
2962    if (strncmp(Char(base), "::", 2) == 0) {
2963      String *oldbase = base;
2964      base = NewString(Char(base) + 2);
2965      Delete(oldbase);
2966    }
2967
2968    String *prefix = SwigType_prefix(ty2);
2969
2970    /* Do a symbol table search on the base type */
2971    while (!n) {
2972      Hash *nstab;
2973      n = Swig_symbol_clookup(base, stab);
2974      if (!n)
2975	break;
2976      if (Strcmp(nodeType(n), "class") == 0)
2977	break;
2978      n = parentNode(n);
2979      if (!n)
2980	break;
2981      nstab = Getattr(n, "sym:symtab");
2982      n = 0;
2983      if ((!nstab) || (nstab == stab)) {
2984	break;
2985      }
2986      stab = nstab;
2987    }
2988    if (n) {
2989      /* Found a match.  Look at the prefix.  We only allow
2990         the cases where where we want a proxy class for the particular type */
2991      if ((Len(prefix) == 0) ||	                // simple type (pass by value)
2992	  (Strcmp(prefix, "p.") == 0) ||	// pointer
2993	  (Strcmp(prefix, "r.") == 0) ||	// reference
2994	  (Strcmp(prefix, "r.p.") == 0) || 	// pointer by reference
2995          SwigType_prefix_is_simple_1D_array(prefix)) { // Simple 1D array (not arrays of pointers/references)
2996	SwigType *cs = Copy(s);
2997	Setattr(classtypes, cs, n);
2998	Delete(cs);
2999      } else {
3000	n = 0;
3001      }
3002    }
3003    Delete(ty2);
3004    Delete(base);
3005    Delete(prefix);
3006  }
3007  if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) {
3008    n = 0;
3009  }
3010
3011  return n;
3012}
3013
3014/* -----------------------------------------------------------------------------
3015 * Language::enumLookup()
3016 *
3017 * Finds and returns the Node containing the enum declaration for the (enum)
3018 * type passed in.
3019 * ----------------------------------------------------------------------------- */
3020
3021Node *Language::enumLookup(SwigType *s) {
3022  Node *n = 0;
3023
3024  /* Look in hash of cached values */
3025  n = Getattr(enumtypes, s);
3026  if (!n) {
3027    Symtab *stab = 0;
3028    SwigType *lt = SwigType_ltype(s);
3029    SwigType *ty1 = SwigType_typedef_resolve_all(lt);
3030    SwigType *ty2 = SwigType_strip_qualifiers(ty1);
3031    Delete(lt);
3032    Delete(ty1);
3033    lt = 0;
3034    ty1 = 0;
3035
3036    String *base = SwigType_base(ty2);
3037
3038    Replaceall(base, "enum ", "");
3039    String *prefix = SwigType_prefix(ty2);
3040
3041    if (strncmp(Char(base), "::", 2) == 0) {
3042      String *oldbase = base;
3043      base = NewString(Char(base) + 2);
3044      Delete(oldbase);
3045    }
3046
3047    /* Look for type in symbol table */
3048    while (!n) {
3049      Hash *nstab;
3050      n = Swig_symbol_clookup(base, stab);
3051      if (!n)
3052	break;
3053      if (Strcmp(nodeType(n), "enum") == 0)
3054	break;
3055      n = parentNode(n);
3056      if (!n)
3057	break;
3058      nstab = Getattr(n, "sym:symtab");
3059      n = 0;
3060      if ((!nstab) || (nstab == stab)) {
3061	break;
3062      }
3063      stab = nstab;
3064    }
3065    if (n) {
3066      /* Found a match.  Look at the prefix.  We only allow simple types. */
3067      if (Len(prefix) == 0) {	/* Simple type */
3068	Setattr(enumtypes, Copy(s), n);
3069      } else {
3070	n = 0;
3071      }
3072    }
3073    Delete(ty2);
3074    Delete(base);
3075    Delete(prefix);
3076  }
3077  if (n && (GetFlag(n, "feature:ignore"))) {
3078    n = 0;
3079  }
3080
3081  return n;
3082}
3083
3084/* -----------------------------------------------------------------------------
3085 * Language::allow_overloading()
3086 * ----------------------------------------------------------------------------- */
3087
3088void Language::allow_overloading(int val) {
3089  overloading = val;
3090}
3091
3092/* -----------------------------------------------------------------------------
3093 * Language::allow_multiple_input()
3094 * ----------------------------------------------------------------------------- */
3095
3096void Language::allow_multiple_input(int val) {
3097  multiinput = val;
3098}
3099
3100/* -----------------------------------------------------------------------------
3101 * Language::enable_cplus_runtime_mode()
3102 * ----------------------------------------------------------------------------- */
3103
3104void Language::enable_cplus_runtime_mode() {
3105  cplus_runtime = 1;
3106}
3107
3108/* -----------------------------------------------------------------------------
3109 * Language::cplus_runtime_mode()
3110 * ----------------------------------------------------------------------------- */
3111
3112int Language::cplus_runtime_mode() {
3113  return cplus_runtime;
3114}
3115
3116/* -----------------------------------------------------------------------------
3117 * Language::allow_directors()
3118 * ----------------------------------------------------------------------------- */
3119
3120void Language::allow_directors(int val) {
3121  directors = val;
3122}
3123
3124/* -----------------------------------------------------------------------------
3125 * Language::directorsEnabled()
3126 * ----------------------------------------------------------------------------- */
3127
3128int Language::directorsEnabled() const {
3129  return director_language && CPlusPlus && (directors || director_mode);
3130}
3131
3132/* -----------------------------------------------------------------------------
3133 * Language::allow_dirprot()
3134 * ----------------------------------------------------------------------------- */
3135
3136void Language::allow_dirprot(int val) {
3137  director_protected_mode = val;
3138}
3139
3140/* -----------------------------------------------------------------------------
3141 * Language::allow_allprotected()
3142 * ----------------------------------------------------------------------------- */
3143
3144void Language::allow_allprotected(int val) {
3145  all_protected_mode = val;
3146}
3147
3148/* -----------------------------------------------------------------------------
3149 * Language::dirprot_mode()
3150 * ----------------------------------------------------------------------------- */
3151
3152int Language::dirprot_mode() const {
3153  return directorsEnabled() ? director_protected_mode : 0;
3154}
3155
3156/* -----------------------------------------------------------------------------
3157 * Language::need_nonpublic_ctor()
3158 * ----------------------------------------------------------------------------- */
3159
3160int Language::need_nonpublic_ctor(Node *n) {
3161  /*
3162     detects when a protected constructor is needed, which is always
3163     the case if 'dirprot' mode is used.  However, if that is not the
3164     case, we will try to strictly emit what is minimal to don't break
3165     the generated, while preserving compatibility with java, which
3166     always try to emit the default constructor.
3167
3168     rules:
3169
3170     - when dirprot mode is used, the protected constructors are
3171     always needed.
3172
3173     - the protected default constructor is always needed.
3174
3175     - if dirprot mode is not used, the protected constructors will be
3176     needed only if:
3177
3178     - there is no any public constructor in the class, and
3179     - there is no protected default constructor
3180
3181     In that case, all the declared protected constructors are
3182     needed since we don't know which one to pick up.
3183
3184     Note: given all the complications here, I am always in favor to
3185     always enable 'dirprot', since is the C++ idea of protected
3186     members, and use %ignore for the method you don't whan to add in
3187     the director class.
3188   */
3189  if (directorsEnabled()) {
3190    if (is_protected(n)) {
3191      if (dirprot_mode()) {
3192	/* when using dirprot mode, the protected constructors are
3193	   always needed */
3194	return 1;
3195      } else {
3196	int is_default_ctor = !ParmList_numrequired(Getattr(n, "parms"));
3197	if (is_default_ctor) {
3198	  /* the default protected constructor is always needed, for java compatibility */
3199	  return 1;
3200	} else {
3201	  /* check if there is a public constructor */
3202	  Node *parent = Swig_methodclass(n);
3203	  int public_ctor = Getattr(parent, "allocate:default_constructor")
3204	      || Getattr(parent, "allocate:public_constructor");
3205	  if (!public_ctor) {
3206	    /* if not, the protected constructor will be needed only
3207	       if there is no protected default constructor declared */
3208	    int no_prot_default_ctor = !Getattr(parent, "allocate:default_base_constructor");
3209	    return no_prot_default_ctor;
3210	  }
3211	}
3212      }
3213    }
3214  }
3215  return 0;
3216}
3217
3218/* -----------------------------------------------------------------------------
3219 * Language::need_nonpublic_member()
3220 * ----------------------------------------------------------------------------- */
3221int Language::need_nonpublic_member(Node *n) {
3222  if (directorsEnabled()) {
3223    if (is_protected(n)) {
3224      if (dirprot_mode()) {
3225	/* when using dirprot mode, the protected members are always needed. */
3226	return 1;
3227      } else {
3228	/* if the method is pure virtual, we need it. */
3229	int pure_virtual = (Cmp(Getattr(n, "value"), "0") == 0);
3230	return pure_virtual;
3231      }
3232    }
3233  }
3234  return 0;
3235}
3236
3237
3238/* -----------------------------------------------------------------------------
3239 * Language::is_smart_pointer()
3240 * ----------------------------------------------------------------------------- */
3241
3242int Language::is_smart_pointer() const {
3243  return SmartPointer;
3244}
3245
3246/* -----------------------------------------------------------------------------
3247 * Language::extraDirectorProtectedCPPMethodsRequired()
3248 * ----------------------------------------------------------------------------- */
3249
3250bool Language::extraDirectorProtectedCPPMethodsRequired() const {
3251  return true;
3252}
3253
3254/* -----------------------------------------------------------------------------
3255 * Language::is_wrapping_class()
3256 * ----------------------------------------------------------------------------- */
3257
3258int Language::is_wrapping_class() {
3259  return InClass;
3260}
3261
3262/* -----------------------------------------------------------------------------
3263 * Language::getCurrentClass()
3264 * ----------------------------------------------------------------------------- */
3265
3266Node *Language::getCurrentClass() const {
3267  return CurrentClass;
3268}
3269
3270/* -----------------------------------------------------------------------------
3271 * Language::getClassName()
3272 * ----------------------------------------------------------------------------- */
3273
3274String *Language::getClassName() const {
3275  return ClassName;
3276}
3277
3278/* -----------------------------------------------------------------------------
3279 * Language::getClassPrefix()
3280 * ----------------------------------------------------------------------------- */
3281
3282String *Language::getClassPrefix() const {
3283  return ClassPrefix;
3284}
3285
3286/* -----------------------------------------------------------------------------
3287 * Language::getClassType()
3288 * ----------------------------------------------------------------------------- */
3289
3290String *Language::getClassType() const {
3291  return ClassType;
3292}
3293
3294/* -----------------------------------------------------------------------------
3295 * Language::abstractClassTest()
3296 * ----------------------------------------------------------------------------- */
3297//#define SWIG_DEBUG
3298int Language::abstractClassTest(Node *n) {
3299  /* check for non public operator new */
3300  if (GetFlag(n, "feature:notabstract"))
3301    return 0;
3302  if (Getattr(n, "allocate:nonew"))
3303    return 1;
3304  /* now check for the rest */
3305  List *abstract = Getattr(n, "abstract");
3306  if (!abstract)
3307    return 0;
3308  int labs = Len(abstract);
3309#ifdef SWIG_DEBUG
3310  List *bases = Getattr(n, "allbases");
3311  Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(bases));
3312#endif
3313  if (!labs)
3314    return 0;			/*strange, but need to be fixed */
3315  if (abstract && !directorsEnabled())
3316    return 1;
3317  if (!GetFlag(n, "feature:director"))
3318    return 1;
3319
3320  Node *dirabstract = 0;
3321  Node *vtable = Getattr(n, "vtable");
3322  if (vtable) {
3323#ifdef SWIG_DEBUG
3324    Printf(stderr, "vtable %s %d %d\n", Getattr(n, "name"), Len(vtable), labs);
3325#endif
3326    for (int i = 0; i < labs; i++) {
3327      Node *ni = Getitem(abstract, i);
3328      Node *method_id = vtable_method_id(ni);
3329      if (!method_id)
3330	continue;
3331      bool exists_item = false;
3332      int len = Len(vtable);
3333      for (int i = 0; i < len; i++) {
3334	Node *item = Getitem(vtable, i);
3335	String *check_item = Getattr(item, "vmid");
3336	if (Strcmp(method_id, check_item) == 0) {
3337	  exists_item = true;
3338	  break;
3339	}
3340      }
3341#ifdef SWIG_DEBUG
3342      Printf(stderr, "method %s %d\n", method_id, exists_item ? 1 : 0);
3343#endif
3344      Delete(method_id);
3345      if (!exists_item) {
3346	dirabstract = ni;
3347	break;
3348      }
3349    }
3350    if (dirabstract) {
3351      if (is_public(dirabstract)) {
3352	Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
3353		     "Director class '%s' is abstract, abstract method '%s' is not accesible, maybe due to multiple inheritance or 'nodirector' feature\n",
3354		     SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
3355      } else {
3356	Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
3357		     "Director class '%s' is abstract, abstract method '%s' is private\n", SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
3358      }
3359      return 1;
3360    }
3361  } else {
3362    return 1;
3363  }
3364  return dirabstract ? 1 : 0;
3365}
3366
3367void Language::setSubclassInstanceCheck(String *nc) {
3368  none_comparison = nc;
3369}
3370
3371void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
3372  Delete(argc_template_string);
3373  argc_template_string = Copy(argc);
3374  Delete(argv_template_string);
3375  argv_template_string = Copy(argv);
3376}
3377
3378int Language::is_assignable(Node *n) {
3379  if (GetFlag(n, "feature:immutable"))
3380    return 0;
3381  SwigType *type = Getattr(n, "type");
3382  Node *cn = 0;
3383  SwigType *ftd = SwigType_typedef_resolve_all(type);
3384  SwigType *td = SwigType_strip_qualifiers(ftd);
3385  if (SwigType_type(td) == T_USER) {
3386    cn = Swig_symbol_clookup(td, 0);
3387    if (cn) {
3388      if ((Strcmp(nodeType(cn), "class") == 0)) {
3389	if (Getattr(cn, "allocate:noassign")) {
3390	  SetFlag(n, "feature:immutable");
3391	  Delete(ftd);
3392	  Delete(td);
3393	  return 0;
3394	}
3395      }
3396    }
3397  }
3398  Delete(ftd);
3399  Delete(td);
3400  return 1;
3401}
3402
3403String *Language::runtimeCode() {
3404  return NewString("");
3405}
3406
3407String *Language::defaultExternalRuntimeFilename() {
3408  return 0;
3409}
3410
3411/* -----------------------------------------------------------------------------
3412 * Language::replaceSpecialVariables()
3413 * Language modules should implement this if special variables are to be handled
3414 * correctly in the $typemap(...) special variable macro.
3415 * method - typemap method name
3416 * tm - string containing typemap contents
3417 * parm - a parameter describing the typemap type to be handled
3418 * ----------------------------------------------------------------------------- */
3419void Language::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
3420  (void)method;
3421  (void)tm;
3422  (void)parm;
3423}
3424
3425Language *Language::instance() {
3426  return this_;
3427}
3428
3429Hash *Language::getClassHash() const {
3430  return classhash;
3431}
3432