PageRenderTime 326ms CodeModel.GetById 30ms app.highlight 190ms RepoModel.GetById 46ms app.codeStats 0ms

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

#
C++ | 2140 lines | 1507 code | 276 blank | 357 comment | 421 complexity | 7f2b03601dec99995795574e464b96aa MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file