PageRenderTime 148ms CodeModel.GetById 2ms app.highlight 131ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Source/Modules/lang.cxx

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