PageRenderTime 121ms CodeModel.GetById 22ms app.highlight 89ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Source/Modules/typepass.cxx

#
C++ | 1234 lines | 969 code | 115 blank | 150 comment | 257 complexity | 137171621df1b2b2f5de1d4adcbbe976 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 * typepass.cxx
  10 *
  11 * This module builds all of the internal type information by collecting
  12 * typedef declarations as well as registering classes, structures, and unions.
  13 * This information is needed to correctly handle shadow classes and other
  14 * advanced features.   This phase of compilation is also used to perform
  15 * type-expansion.  All types are fully qualified with namespace prefixes
  16 * and other information needed for compilation.
  17 * ----------------------------------------------------------------------------- */
  18
  19char cvsroot_typepass_cxx[] = "$Id: typepass.cxx 12953 2012-03-25 19:10:33Z wsfulton $";
  20
  21#include "swigmod.h"
  22#include "cparse.h"
  23
  24struct normal_node {
  25  Symtab *symtab;
  26  Hash *typescope;
  27  List *normallist;
  28  normal_node *next;
  29};
  30
  31static normal_node *patch_list = 0;
  32
  33/* Singleton class - all non-static methods in this class are private */
  34class TypePass:private Dispatcher {
  35  Node *inclass;
  36  Node *module;
  37  int importmode;
  38  String *nsname;
  39  String *nssymname;
  40  Hash *classhash;
  41  List *normalize;
  42
  43  TypePass() {
  44  }
  45
  46  /* Normalize a type. Replaces type with fully qualified version */
  47  void normalize_type(SwigType *ty) {
  48    SwigType *qty;
  49    if (CPlusPlus) {
  50      Replaceall(ty, "struct ", "");
  51      Replaceall(ty, "union ", "");
  52      Replaceall(ty, "class ", "");
  53    }
  54
  55    qty = SwigType_typedef_qualified(ty);
  56    /*    Printf(stdout,"%s --> %s\n", ty, qty); */
  57    Clear(ty);
  58    Append(ty, qty);
  59    Delete(qty);
  60  }
  61
  62  /* Normalize a parameter list */
  63
  64  void normalize_parms(ParmList *p) {
  65    while (p) {
  66      SwigType *ty = Getattr(p, "type");
  67      normalize_type(ty);
  68      /* This is a check for a function type */
  69      {
  70	SwigType *qty = SwigType_typedef_resolve_all(ty);
  71	if (SwigType_isfunction(qty)) {
  72	  SwigType_add_pointer(ty);
  73	}
  74	Delete(qty);
  75      }
  76
  77      String *value = Getattr(p, "value");
  78      if (value) {
  79	Node *n = Swig_symbol_clookup(value, 0);
  80	if (n) {
  81	  String *q = Swig_symbol_qualified(n);
  82	  if (q && Len(q)) {
  83	    String *vb = Swig_scopename_last(value);
  84	    Clear(value);
  85	    Printf(value, "%s::%s", SwigType_namestr(q), vb);
  86	    Delete(q);
  87	  }
  88	}
  89      }
  90      if (value && SwigType_istemplate(value)) {
  91	String *nv = SwigType_namestr(value);
  92	Setattr(p, "value", nv);
  93      }
  94      p = nextSibling(p);
  95    }
  96  }
  97
  98  void normalize_later(ParmList *p) {
  99    while (p) {
 100      SwigType *ty = Getattr(p, "type");
 101      Append(normalize, ty);
 102      p = nextSibling(p);
 103    }
 104  }
 105
 106  /* Walk through entries in normalize list and patch them up */
 107  void normalize_list() {
 108    Hash *currentsym = Swig_symbol_current();
 109
 110    normal_node *nn = patch_list;
 111    normal_node *np;
 112    while (nn) {
 113      Swig_symbol_setscope(nn->symtab);
 114      SwigType_set_scope(nn->typescope);
 115      Iterator t;
 116      for (t = First(nn->normallist); t.item; t = Next(t)) {
 117	normalize_type(t.item);
 118      }
 119      Delete(nn->normallist);
 120      np = nn->next;
 121      delete(nn);
 122      nn = np;
 123    }
 124    Swig_symbol_setscope(currentsym);
 125  }
 126
 127  /* generate C++ inheritance type-relationships */
 128  void cplus_inherit_types_impl(Node *first, Node *cls, String *clsname, const char *bases, const char *baselist, int ispublic, String *cast = 0) {
 129
 130    if (first == cls)
 131      return;			/* The Marcelo check */
 132    if (!cls)
 133      cls = first;
 134    List *alist = 0;
 135    List *ilist = Getattr(cls, bases);
 136    if (!ilist) {
 137      List *nlist = Getattr(cls, baselist);
 138      if (nlist) {
 139	int len = Len(nlist);
 140	int i;
 141	for (i = 0; i < len; i++) {
 142	  Node *bcls = 0;
 143	  int clsforward = 0;
 144	  String *bname = Getitem(nlist, i);
 145	  String *sname = bname;
 146	  String *tname = 0;
 147
 148	  /* Try to locate the base class.   We look in the symbol table and we chase 
 149	     typedef declarations to get to the base class if necessary */
 150	  Symtab *st = Getattr(cls, "sym:symtab");
 151
 152	  if (SwigType_istemplate(bname)) {
 153	    tname = SwigType_typedef_resolve_all(bname);
 154	    sname = tname;
 155	  }
 156	  while (1) {
 157	    String *qsname = SwigType_typedef_qualified(sname);
 158	    bcls = Swig_symbol_clookup(qsname, st);
 159	    Delete(qsname);
 160	    if (bcls) {
 161	      if (Strcmp(nodeType(bcls), "class") != 0) {
 162		/* Not a class.   The symbol could be a typedef. */
 163		if (checkAttribute(bcls, "storage", "typedef")) {
 164		  SwigType *decl = Getattr(bcls, "decl");
 165		  if (!decl || !(Len(decl))) {
 166		    sname = Getattr(bcls, "type");
 167		    st = Getattr(bcls, "sym:symtab");
 168		    if (SwigType_istemplate(sname)) {
 169		      if (tname)
 170			Delete(tname);
 171		      tname = SwigType_typedef_resolve_all(sname);
 172		      sname = tname;
 173		    }
 174		    continue;
 175		  }
 176		}
 177		if (Strcmp(nodeType(bcls), "classforward") != 0) {
 178		  Swig_error(Getfile(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
 179		  Swig_error(Getfile(bcls), Getline(bcls), "See definition of '%s'.\n", SwigType_namestr(bname));
 180		} else {
 181		  Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bname), Getline(bname), "Base class '%s' is incomplete.\n", SwigType_namestr(bname));
 182		  Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname));
 183		  clsforward = 1;
 184		}
 185		bcls = 0;
 186	      } else {
 187		if (Getattr(bcls, "typepass:visit")) {
 188		  if (!ilist)
 189		    ilist = alist = NewList();
 190		  Append(ilist, bcls);
 191		} else {
 192		  Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname));
 193		  Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "'%s' must be defined before it is used as a base class.\n", SwigType_namestr(bname));
 194		}
 195	      }
 196	    }
 197	    break;
 198	  }
 199
 200	  if (tname)
 201	    Delete(tname);
 202	  if (!bcls) {
 203	    if (!clsforward) {
 204	      if (ispublic && !Getmeta(bname, "already_warned")) {
 205		Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
 206		if (Strchr(bname, '<')) {
 207		  Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname));
 208		}
 209		Setmeta(bname, "already_warned", "1");
 210	      }
 211	    }
 212	    SwigType_inherit(clsname, bname, cast, 0);
 213	  }
 214	}
 215      }
 216      if (ilist) {
 217	Setattr(cls, bases, ilist);
 218      }
 219    }
 220    if (alist)
 221      Delete(alist);
 222
 223    if (!ilist)
 224      return;
 225    int len = Len(ilist);
 226    int i;
 227    for (i = 0; i < len; i++) {
 228      Node *n = Getitem(ilist, i);
 229      String *bname = Getattr(n, "name");
 230      Node *bclass = n;		/* Getattr(n,"class"); */
 231      Hash *scopes = Getattr(bclass, "typescope");
 232      SwigType_inherit(clsname, bname, cast, 0);
 233      String *smartptr = Getattr(first, "feature:smartptr");
 234      if (smartptr) {
 235	SwigType *smart = 0;
 236	SwigType *spt = Swig_cparse_type(smartptr);
 237	if (spt) {
 238	  smart = SwigType_typedef_resolve_all(spt);
 239	  Delete(spt);
 240	  /* Record a (fake) inheritance relationship between smart pointer
 241	     and smart pointer to base class, so that smart pointer upcasts
 242	     are automatically generated. */
 243          SwigType *bsmart = Copy(smart);
 244          SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
 245          SwigType *rbname = SwigType_typedef_resolve_all(bname);
 246	  Replaceall(bsmart, rclsname, rbname);
 247          Delete(rclsname);
 248          Delete(rbname);
 249	  String *smartnamestr = SwigType_namestr(smart);
 250	  String *bsmartnamestr = SwigType_namestr(bsmart);
 251	  /* construct casting code */
 252	  String *convcode = NewStringf("\n    *newmemory = SWIG_CAST_NEW_MEMORY;\n    return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
 253	  Delete(bsmartnamestr);
 254	  Delete(smartnamestr);
 255	  /* setup inheritance relationship between smart pointer templates */
 256	  SwigType_inherit(smart, bsmart, 0, convcode);
 257	  if (!GetFlag(bclass, "feature:smartptr"))
 258	    Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
 259	  Delete(convcode);
 260	  Delete(bsmart);
 261	  Delete(smart);
 262	} else {
 263	  Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(smartptr), SwigType_namestr(clsname));
 264	}
 265      } else {
 266	if (GetFlag(bclass, "feature:smartptr"))
 267	  Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name")));
 268      }
 269      if (!importmode) {
 270	String *btype = Copy(bname);
 271	SwigType_add_pointer(btype);
 272	SwigType_remember(btype);
 273	Delete(btype);
 274      }
 275      if (scopes) {
 276	SwigType_inherit_scope(scopes);
 277      }
 278      /* Set up inheritance in the symbol table */
 279      Symtab *st = Getattr(cls, "symtab");
 280      Symtab *bst = Getattr(bclass, "symtab");
 281      if (st == bst) {
 282	Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", SwigType_namestr(Getattr(cls, "name")));
 283	continue;
 284      }
 285      Symtab *s = Swig_symbol_current();
 286      Swig_symbol_setscope(st);
 287      Swig_symbol_inherit(bst);
 288      Swig_symbol_setscope(s);
 289
 290      /* Recursively hit base classes */
 291      String *namestr = SwigType_namestr(Getattr(bclass, "name"));
 292      String *newcast = NewStringf("(%s *)%s", namestr, cast);
 293      Delete(namestr);
 294      cplus_inherit_types_impl(first, bclass, clsname, bases, baselist, ispublic, newcast);
 295      Delete(newcast);
 296    }
 297  }
 298
 299  void append_list(List *lb, List *la) {
 300    if (la && lb) {
 301      for (Iterator bi = First(la); bi.item; bi = Next(bi)) {
 302	Append(lb, bi.item);
 303      }
 304    }
 305  }
 306
 307  void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
 308    cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast);
 309    cplus_inherit_types_impl(first, cls, clsname, "protectedbases", "protectedbaselist", 0, cast);
 310    cplus_inherit_types_impl(first, cls, clsname, "privatebases", "privatebaselist", 0, cast);
 311
 312    if (!cls)
 313      cls = first;
 314
 315    List *allbases = NewList();
 316    append_list(allbases, Getattr(cls, "bases"));
 317    append_list(allbases, Getattr(cls, "protectedbases"));
 318    append_list(allbases, Getattr(cls, "privatebases"));
 319    if (Len(allbases)) {
 320      Setattr(cls, "allbases", allbases);
 321    }
 322    Delete(allbases);
 323  }
 324
 325  /* ------------------------------------------------------------
 326   * top()
 327   * ------------------------------------------------------------ */
 328
 329  virtual int top(Node *n) {
 330    importmode = 0;
 331    module = Getattr(n, "module");
 332    inclass = 0;
 333    normalize = 0;
 334    nsname = 0;
 335    nssymname = 0;
 336    classhash = Getattr(n, "classes");
 337    emit_children(n);
 338    normalize_list();
 339    SwigType_set_scope(0);
 340    return SWIG_OK;
 341  }
 342
 343
 344  /* ------------------------------------------------------------
 345   * moduleDirective()
 346   * ------------------------------------------------------------ */
 347
 348  virtual int moduleDirective(Node *n) {
 349    if (!module) {
 350      module = n;
 351    }
 352    return SWIG_OK;
 353  }
 354
 355  /* ------------------------------------------------------------
 356   * importDirective()
 357   * ------------------------------------------------------------ */
 358
 359  virtual int importDirective(Node *n) {
 360    String *oldmodule = module;
 361    int oldimport = importmode;
 362    importmode = 1;
 363    module = 0;
 364    emit_children(n);
 365    importmode = oldimport;
 366    module = oldmodule;
 367    return SWIG_OK;
 368  }
 369
 370  /* ------------------------------------------------------------
 371   * includeDirective()
 372   * externDirective()
 373   * extendDirective()
 374   * ------------------------------------------------------------ */
 375
 376  virtual int includeDirective(Node *n) {
 377    return emit_children(n);
 378  }
 379  virtual int externDeclaration(Node *n) {
 380    return emit_children(n);
 381  }
 382  virtual int extendDirective(Node *n) {
 383    return emit_children(n);
 384  }
 385
 386  /* ------------------------------------------------------------
 387   * classDeclaration()
 388   * ------------------------------------------------------------ */
 389
 390  virtual int classDeclaration(Node *n) {
 391    String *name = Getattr(n, "name");
 392    String *tdname = Getattr(n, "tdname");
 393    String *unnamed = Getattr(n, "unnamed");
 394    String *storage = Getattr(n, "storage");
 395    String *kind = Getattr(n, "kind");
 396    Node *oldinclass = inclass;
 397    List *olist = normalize;
 398    Symtab *symtab;
 399    String *nname = 0;
 400    String *fname = 0;
 401    String *scopename = 0;
 402    String *template_default_expanded = 0;
 403
 404    normalize = NewList();
 405
 406    if (name) {
 407      if (SwigType_istemplate(name)) {
 408	// We need to fully resolve the name and expand default template parameters to make templates work correctly */
 409	Node *cn;
 410	SwigType *resolved_name = SwigType_typedef_resolve_all(name);
 411	SwigType *deftype_name = Swig_symbol_template_deftype(resolved_name, 0);
 412	fname = Copy(resolved_name);
 413	if (!Equal(resolved_name, deftype_name))
 414	  template_default_expanded = Copy(deftype_name);
 415	if (!Equal(fname, name) && (cn = Swig_symbol_clookup_local(fname, 0))) {
 416	  if ((n == cn)
 417	      || (Strcmp(nodeType(cn), "template") == 0)
 418	      || (Getattr(cn, "feature:onlychildren") != 0)
 419	      || (Getattr(n, "feature:onlychildren") != 0)) {
 420	    Swig_symbol_cadd(fname, n);
 421	    if (template_default_expanded)
 422	      Swig_symbol_cadd(template_default_expanded, n);
 423	    SwigType_typedef_class(fname);
 424	    scopename = Copy(fname);
 425	  } else {
 426	    Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
 427	    Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
 428	    scopename = 0;
 429	  }
 430	} else {
 431	  Swig_symbol_cadd(fname, n);
 432	  SwigType_typedef_class(fname);
 433	  scopename = Copy(fname);
 434	}
 435	Delete(deftype_name);
 436	Delete(resolved_name);
 437      } else {
 438	if ((CPlusPlus) || (unnamed)) {
 439	  SwigType_typedef_class(name);
 440	} else {
 441	  SwigType_typedef_class(NewStringf("%s %s", kind, name));
 442	}
 443	scopename = Copy(name);
 444      }
 445    } else {
 446      scopename = 0;
 447    }
 448
 449    Setattr(n, "typepass:visit", "1");
 450
 451    /* Need to set up a typedef if unnamed */
 452    if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
 453      SwigType_typedef(unnamed, tdname);
 454    }
 455
 456    if (nsname && name) {
 457      nname = NewStringf("%s::%s", nsname, name);
 458      String *tdname = Getattr(n, "tdname");
 459      if (tdname) {
 460	tdname = NewStringf("%s::%s", nsname, tdname);
 461	Setattr(n, "tdname", tdname);
 462      }
 463    }
 464    if (nssymname) {
 465      if (GetFlag(n, "feature:nspace"))
 466	Setattr(n, "sym:nspace", nssymname);
 467    }
 468    SwigType_new_scope(scopename);
 469    SwigType_attach_symtab(Getattr(n, "symtab"));
 470
 471    /* Inherit type definitions into the class */
 472    if (name) {
 473      cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
 474    }
 475
 476    inclass = n;
 477    symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
 478    emit_children(n);
 479    Swig_symbol_setscope(symtab);
 480
 481    Hash *ts = SwigType_pop_scope();
 482    Setattr(n, "typescope", ts);
 483    Delete(ts);
 484    Setattr(n, "module", module);
 485
 486    // When a fully qualified templated type with default parameters is used in the parsed code, 
 487    // the following additional symbols and scopes are needed for successful lookups
 488    if (template_default_expanded) {
 489      Swig_symbol_alias(template_default_expanded, Getattr(n, "symtab"));
 490      SwigType_scope_alias(template_default_expanded, Getattr(n, "typescope"));
 491    }
 492
 493    /* Normalize deferred types */
 494    {
 495      normal_node *nn = new normal_node();
 496      nn->normallist = normalize;
 497      nn->symtab = Getattr(n, "symtab");
 498      nn->next = patch_list;
 499      nn->typescope = Getattr(n, "typescope");
 500      patch_list = nn;
 501    }
 502
 503    normalize = olist;
 504
 505    inclass = oldinclass;
 506
 507    /* If in a namespace, patch the class name */
 508    if (nname) {
 509      Setattr(n, "name", nname);
 510      Delete(nname);
 511    }
 512    Delete(fname);
 513    return SWIG_OK;
 514  }
 515
 516  /* ------------------------------------------------------------
 517   * namespaceDeclaration()
 518   * ------------------------------------------------------------ */
 519
 520  virtual int templateDeclaration(Node *n) {
 521    String *name = Getattr(n, "name");
 522    String *ttype = Getattr(n, "templatetype");
 523    if (Strcmp(ttype, "class") == 0) {
 524      String *rname = SwigType_typedef_resolve_all(name);
 525      SwigType_typedef_class(rname);
 526      Delete(rname);
 527    } else if (Strcmp(ttype, "classforward") == 0) {
 528      String *rname = SwigType_typedef_resolve_all(name);
 529      SwigType_typedef_class(rname);
 530      Delete(rname);
 531      /*      SwigType_typedef_class(name); */
 532    }
 533    return SWIG_OK;
 534  }
 535
 536  /* ------------------------------------------------------------
 537   * classforwardDeclaration()
 538   * ------------------------------------------------------------ */
 539
 540  virtual int classforwardDeclaration(Node *n) {
 541
 542    /* Can't do inside a C struct because it breaks C nested structure wrapping */
 543    if ((!inclass) || (CPlusPlus)) {
 544      String *name = Getattr(n, "name");
 545      SwigType_typedef_class(name);
 546    }
 547    return SWIG_OK;
 548  }
 549
 550  /* ------------------------------------------------------------
 551   * namespaceDeclaration()
 552   * ------------------------------------------------------------ */
 553
 554  virtual int namespaceDeclaration(Node *n) {
 555    Symtab *symtab;
 556    String *name = Getattr(n, "name");
 557    String *alias = Getattr(n, "alias");
 558    List *olist = normalize;
 559    normalize = NewList();
 560    if (alias) {
 561      Typetab *ts = Getattr(n, "typescope");
 562      if (!ts) {
 563	Node *ns;
 564	/* Create a empty scope for the alias */
 565	ns = Getattr(n, "namespace");
 566	if (ns) {
 567	  SwigType_scope_alias(name, Getattr(ns, "typescope"));
 568	}
 569	ts = Getattr(ns, "typescope");
 570	Setattr(n, "typescope", ts);
 571      }
 572      /* Namespace alias */
 573      return SWIG_OK;
 574    } else {
 575      if (name) {
 576	Node *nn = Swig_symbol_clookup(name, n);
 577	Hash *ts = 0;
 578	if (nn)
 579	  ts = Getattr(nn, "typescope");
 580	if (!ts) {
 581	  SwigType_new_scope(name);
 582	  SwigType_attach_symtab(Getattr(n, "symtab"));
 583	} else {
 584	  SwigType_set_scope(ts);
 585	}
 586      }
 587      String *oldnsname = nsname;
 588      String *oldnssymname = nssymname;
 589      nsname = Swig_symbol_qualified(Getattr(n, "symtab"));
 590      nssymname = Swig_symbol_qualified_language_scopename(Getattr(n, "symtab"));
 591      symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
 592      emit_children(n);
 593      Swig_symbol_setscope(symtab);
 594
 595      if (name) {
 596	Hash *ts = SwigType_pop_scope();
 597	Setattr(n, "typescope", ts);
 598	Delete(ts);
 599      }
 600
 601      /* Normalize deferred types */
 602      {
 603	normal_node *nn = new normal_node();
 604	nn->normallist = normalize;
 605	nn->symtab = Getattr(n, "symtab");
 606	nn->next = patch_list;
 607	nn->typescope = Getattr(n, "typescope");
 608	patch_list = nn;
 609      }
 610      normalize = olist;
 611
 612      Delete(nssymname);
 613      nssymname = oldnssymname;
 614      Delete(nsname);
 615      nsname = oldnsname;
 616      return SWIG_OK;
 617    }
 618  }
 619
 620  /* ------------------------------------------------------------
 621   * cDeclaration()
 622   * ------------------------------------------------------------ */
 623
 624  virtual int cDeclaration(Node *n) {
 625    if (NoExcept) {
 626      Delattr(n, "throws");
 627    }
 628
 629    /* Normalize types. */
 630    SwigType *ty = Getattr(n, "type");
 631    normalize_type(ty);
 632    SwigType *decl = Getattr(n, "decl");
 633    if (decl) {
 634      normalize_type(decl);
 635    }
 636    normalize_parms(Getattr(n, "parms"));
 637    normalize_parms(Getattr(n, "throws"));
 638    if (GetFlag(n, "conversion_operator")) {
 639      /* The call to the operator in the generated wrapper must be fully qualified in order to compile */
 640      SwigType *name = Getattr(n, "name");
 641      SwigType *qualifiedname = Swig_symbol_string_qualify(name,0);
 642      Clear(name);
 643      Append(name, qualifiedname);
 644      Delete(qualifiedname);
 645    }
 646
 647    if (checkAttribute(n, "storage", "typedef")) {
 648      String *name = Getattr(n, "name");
 649      ty = Getattr(n, "type");
 650      decl = Getattr(n, "decl");
 651      SwigType *t = Copy(ty);
 652      {
 653	/* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */
 654	if (Swig_scopename_check(t) && strncmp(Char(t), "::", 2)) {
 655	  String *base, *prefix, *qprefix;
 656	  base = Swig_scopename_last(t);
 657	  prefix = Swig_scopename_prefix(t);
 658	  qprefix = SwigType_typedef_qualified(prefix);
 659	  Delete(t);
 660	  t = NewStringf("%s::%s", qprefix, base);
 661	  Delete(base);
 662	  Delete(prefix);
 663	  Delete(qprefix);
 664	}
 665      }
 666      SwigType_push(t, decl);
 667      if (CPlusPlus) {
 668	Replaceall(t, "struct ", "");
 669	Replaceall(t, "union ", "");
 670	Replaceall(t, "class ", "");
 671      }
 672      SwigType_typedef(t, name);
 673    }
 674    /* If namespaces are active.  We need to patch the name with a namespace prefix */
 675    if (nsname && !inclass) {
 676      String *name = Getattr(n, "name");
 677      if (name) {
 678	String *nname = NewStringf("%s::%s", nsname, name);
 679	Setattr(n, "name", nname);
 680	Delete(nname);
 681      }
 682    }
 683    clean_overloaded(n);
 684    return SWIG_OK;
 685  }
 686
 687
 688  /* ------------------------------------------------------------
 689   * constructorDeclaration()
 690   * ------------------------------------------------------------ */
 691
 692  virtual int constructorDeclaration(Node *n) {
 693    if (NoExcept) {
 694      Delattr(n, "throws");
 695    }
 696
 697    normalize_parms(Getattr(n, "parms"));
 698    normalize_parms(Getattr(n, "throws"));
 699
 700    /* If in a namespace, patch the class name */
 701    if (nsname) {
 702      String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
 703      Setattr(n, "name", nname);
 704    }
 705    clean_overloaded(n);
 706    return SWIG_OK;
 707  }
 708
 709  /* ------------------------------------------------------------
 710   * destructorDeclaration()
 711   * ------------------------------------------------------------ */
 712
 713  virtual int destructorDeclaration(Node *n) {
 714    /* If in a namespace, patch the class name */
 715    if (nsname) {
 716      String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
 717      Setattr(n, "name", nname);
 718    }
 719    return SWIG_OK;
 720  }
 721
 722  /* ------------------------------------------------------------
 723   * constantDirective()
 724   * ------------------------------------------------------------ */
 725
 726  virtual int constantDirective(Node *n) {
 727    SwigType *ty = Getattr(n, "type");
 728    if (ty) {
 729      Setattr(n, "type", SwigType_typedef_qualified(ty));
 730    }
 731    return SWIG_OK;
 732  }
 733
 734
 735  /* ------------------------------------------------------------
 736   * enumDeclaration()
 737   * ------------------------------------------------------------ */
 738
 739  virtual int enumDeclaration(Node *n) {
 740    String *name = Getattr(n, "name");
 741
 742    if (name) {
 743      String *scope = 0;
 744
 745      // Add a typedef to the type table so that we can use 'enum Name' as well as just 'Name'
 746      if (nsname || inclass) {
 747
 748	// But first correct the name and tdname to contain the fully qualified scopename
 749	if (nsname && inclass) {
 750	  scope = NewStringf("%s::%s", nsname, Getattr(inclass, "name"));
 751	} else if (nsname) {
 752	  scope = NewStringf("%s", nsname);
 753	} else if (inclass) {
 754	  scope = NewStringf("%s", Getattr(inclass, "name"));
 755	}
 756
 757	String *nname = NewStringf("%s::%s", scope, name);
 758	Setattr(n, "name", nname);
 759
 760	String *tdname = Getattr(n, "tdname");
 761	if (tdname) {
 762	  tdname = NewStringf("%s::%s", scope, tdname);
 763	  Setattr(n, "tdname", tdname);
 764	}
 765
 766	SwigType *t = NewStringf("enum %s", nname);
 767	SwigType_typedef(t, name);
 768      } else {
 769	SwigType *t = NewStringf("enum %s", name);
 770	SwigType_typedef(t, name);
 771      }
 772      Delete(scope);
 773    }
 774
 775    String *tdname = Getattr(n, "tdname");
 776    String *unnamed = Getattr(n, "unnamed");
 777    String *storage = Getattr(n, "storage");
 778
 779    // Construct enumtype - for declaring an enum of this type with SwigType_ltype() etc
 780    String *enumtype = 0;
 781    if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
 782      enumtype = Copy(Getattr(n, "tdname"));
 783    } else if (name) {
 784      enumtype = NewStringf("%s%s", CPlusPlus ? "" : "enum ", Getattr(n, "name"));
 785    } else {
 786      // anonymous enums
 787      enumtype = Copy(Getattr(n, "type"));
 788    }
 789    Setattr(n, "enumtype", enumtype);
 790
 791    if (nssymname) {
 792      if (GetFlag(n, "feature:nspace"))
 793	Setattr(n, "sym:nspace", nssymname);
 794    }
 795
 796    // This block of code is for dealing with %ignore on an enum item where the target language
 797    // attempts to use the C enum value in the target language itself and expects the previous enum value
 798    // to be one more than the previous value... the previous enum item might not exist if it is ignored!
 799    // - It sets the first non-ignored enum item with the "firstenumitem" attribute.
 800    // - It adds an enumvalue attribute if the previous enum item is ignored
 801    {
 802      Node *c;
 803      int count = 0;
 804      String *previous = 0;
 805      bool previous_ignored = false;
 806      bool firstenumitem = false;
 807      for (c = firstChild(n); c; c = nextSibling(c)) {
 808	assert(strcmp(Char(nodeType(c)), "enumitem") == 0);
 809
 810	bool reset;
 811	String *enumvalue = Getattr(c, "enumvalue");
 812	if (GetFlag(c, "feature:ignore") || !Getattr(c, "sym:name")) {
 813	  reset = enumvalue ? true : false;
 814	  previous_ignored = true;
 815	} else {
 816	  if (!enumvalue && previous_ignored) {
 817	    if (previous)
 818	      Setattr(c, "enumvalue", NewStringf("(%s) + %d", previous, count+1));
 819	    else
 820	      Setattr(c, "enumvalue", NewStringf("%d", count));
 821	    SetFlag(c, "virtenumvalue"); // identify enumvalue as virtual, ie not from the parsed source
 822	  }
 823	  if (!firstenumitem) {
 824	    SetFlag(c, "firstenumitem");
 825	    firstenumitem = true;
 826	  }
 827	  reset = true;
 828	  previous_ignored = false;
 829	}
 830	if (reset) {
 831	  previous = enumvalue ? enumvalue : Getattr(c, "name");
 832	  count = 0;
 833	} else {
 834	  count++;
 835	}
 836      }
 837    }
 838
 839    emit_children(n);
 840    return SWIG_OK;
 841  }
 842
 843  /* ------------------------------------------------------------
 844   * enumvalueDeclaration()
 845   * ------------------------------------------------------------ */
 846
 847  virtual int enumvalueDeclaration(Node *n) {
 848    String *name = Getattr(n, "name");
 849    String *value = Getattr(n, "value");
 850    if (!value)
 851      value = name;
 852    if (Strcmp(value, name) == 0) {
 853      String *new_value;
 854      if ((nsname || inclass) && cparse_cplusplus) {
 855	new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
 856      } else {
 857	new_value = NewString(value);
 858      }
 859      if ((nsname || inclass) && !cparse_cplusplus) {
 860	String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
 861	Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */
 862      }
 863      Setattr(n, "value", new_value);
 864      Delete(new_value);
 865    }
 866    Node *next = nextSibling(n);
 867
 868    // Make up an enumvalue if one was not specified in the parsed code (not designed to be used on enum items and %ignore - enumvalue will be set instead)
 869    if (!GetFlag(n, "feature:ignore")) {
 870      if (Getattr(n, "_last") && !Getattr(n, "enumvalue")) {	// Only the first enum item has _last set (Note: first non-ignored enum item has firstenumitem set)
 871	Setattr(n, "enumvalueex", "0");
 872      }
 873      if (next && !Getattr(next, "enumvalue")) {
 874	Setattr(next, "enumvalueex", NewStringf("%s + 1", Getattr(n, "sym:name")));
 875      }
 876    }
 877
 878    return SWIG_OK;
 879  }
 880
 881  /* ------------------------------------------------------------
 882   * enumforwardDeclaration()
 883   * ------------------------------------------------------------ */
 884
 885  virtual int enumforwardDeclaration(Node *n) {
 886
 887    // Use enumDeclaration() to do all the hard work.
 888    // Note that no children can be emitted in a forward declaration as there aren't any.
 889    return enumDeclaration(n);
 890  }
 891
 892#ifdef DEBUG_OVERLOADED
 893  static void show_overloaded(Node *n) {
 894    Node *c = Getattr(n, "sym:overloaded");
 895    Node *checkoverloaded = c;
 896    Printf(stdout, "-------------------- overloaded start %s sym:overloaded():%p -------------------------------\n", Getattr(n, "name"), c);
 897    while (c) {
 898      if (Getattr(c, "error")) {
 899        c = Getattr(c, "sym:nextSibling");
 900        continue;
 901      }
 902      if (Getattr(c, "sym:overloaded") != checkoverloaded) {
 903        Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
 904        Swig_print_node(c);
 905        exit (1);
 906      }
 907
 908      String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
 909      Printf(stdout, "  show_overloaded %s::%s(%s)          [%s] nodeType:%s\n", parentNode(c) ? Getattr(parentNode(c), "name") : "NOPARENT", Getattr(c, "name"), decl, Getattr(c, "sym:overname"), nodeType(c));
 910      if (!Getattr(c, "sym:overloaded")) {
 911        Printf(stdout, "sym:overloaded error.....%p\n", c);
 912        Swig_print_node(c);
 913        exit (1);
 914      }
 915      c = Getattr(c, "sym:nextSibling");
 916    }
 917    Printf(stdout, "-------------------- overloaded end   %s -------------------------------\n", Getattr(n, "name"));
 918  }
 919#endif
 920
 921  /* ------------------------------------------------------------
 922   * usingDeclaration()
 923   * ------------------------------------------------------------ */
 924
 925  virtual int usingDeclaration(Node *n) {
 926    if (Getattr(n, "namespace")) {
 927      /* using namespace id */
 928
 929      /* For a namespace import.   We set up inheritance in the type system */
 930      Node *ns = Getattr(n, "node");
 931      if (ns) {
 932	Typetab *ts = Getattr(ns, "typescope");
 933	if (ts) {
 934	  SwigType_using_scope(ts);
 935	}
 936      }
 937      return SWIG_OK;
 938    } else {
 939      Node *ns;
 940      /* using id */
 941      Symtab *stab = Getattr(n, "sym:symtab");
 942      if (stab) {
 943	String *uname = Getattr(n, "uname");
 944	ns = Swig_symbol_clookup(uname, stab);
 945	if (!ns && SwigType_istemplate(uname)) {
 946	  String *tmp = Swig_symbol_template_deftype(uname, 0);
 947	  if (!Equal(tmp, uname)) {
 948	    ns = Swig_symbol_clookup(tmp, stab);
 949	  }
 950	  Delete(tmp);
 951	}
 952      } else {
 953	ns = 0;
 954      }
 955      if (!ns) {
 956	if (is_public(n)) {
 957	  Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname")));
 958	}
 959      } else {
 960	/* Only a single symbol is being used.  There are only a few symbols that
 961	   we actually care about.  These are typedef, class declarations, and enum */
 962	String *ntype = nodeType(ns);
 963	if (Strcmp(ntype, "cdecl") == 0) {
 964	  if (checkAttribute(ns, "storage", "typedef")) {
 965	    /* A typedef declaration */
 966	    String *uname = Getattr(n, "uname");
 967	    SwigType_typedef_using(uname);
 968	  } else {
 969	    /* A normal C declaration. */
 970	    if ((inclass) && (!GetFlag(n, "feature:ignore")) && (Getattr(n, "sym:name"))) {
 971	      Node *c = ns;
 972	      Node *unodes = 0, *last_unodes = 0;
 973	      int ccount = 0;
 974	      String *symname = Getattr(n, "sym:name");
 975	      while (c) {
 976		if (Strcmp(nodeType(c), "cdecl") == 0) {
 977		  if (!(checkAttribute(c, "storage", "static")
 978			|| checkAttribute(c, "storage", "typedef")
 979			|| checkAttribute(c, "storage", "friend")
 980			|| (Getattr(c, "feature:extend") && !Getattr(c, "code"))
 981			|| GetFlag(c, "feature:ignore"))) {
 982
 983		    /* Don't generate a method if the method is overridden in this class, 
 984		     * for example don't generate another m(bool) should there be a Base::m(bool) :
 985		     * struct Derived : Base { 
 986		     *   void m(bool);
 987		     *   using Base::m;
 988		     * };
 989		     */
 990		    String *csymname = Getattr(c, "sym:name");
 991		    if (!csymname || (Strcmp(csymname, symname) == 0)) {
 992		      {
 993			String *decl = Getattr(c, "decl");
 994			Node *over = Getattr(n, "sym:overloaded");
 995			int match = 0;
 996			while (over) {
 997			  String *odecl = Getattr(over, "decl");
 998			  if (Cmp(decl, odecl) == 0) {
 999			    match = 1;
1000			    break;
1001			  }
1002			  over = Getattr(over, "sym:nextSibling");
1003			}
1004			if (match) {
1005			  c = Getattr(c, "csym:nextSibling");
1006			  continue;
1007			}
1008		      }
1009		      Node *nn = copyNode(c);
1010		      Delattr(nn, "access");	// access might be different from the method in the base class
1011		      Setattr(nn, "access", Getattr(n, "access"));
1012		      if (!Getattr(nn, "sym:name"))
1013			Setattr(nn, "sym:name", symname);
1014
1015		      if (!GetFlag(nn, "feature:ignore")) {
1016			ParmList *parms = CopyParmList(Getattr(c, "parms"));
1017			int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
1018			int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
1019			Setattr(nn, "parms", parms);
1020			Delete(parms);
1021			if (Getattr(n, "feature:extend")) {
1022			  String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
1023
1024			  for (ParmList *p = parms; p;) {
1025			    Append(ucode, Getattr(p, "name"));
1026			    p = nextSibling(p);
1027			    if (p)
1028			      Append(ucode, ",");
1029			  }
1030			  Append(ucode, "); }");
1031			  Setattr(nn, "code", ucode);
1032			  Delete(ucode);
1033			}
1034			ParmList *throw_parm_list = Getattr(c, "throws");
1035			if (throw_parm_list)
1036			  Setattr(nn, "throws", CopyParmList(throw_parm_list));
1037			ccount++;
1038			if (!last_unodes) {
1039			  last_unodes = nn;
1040			  unodes = nn;
1041			} else {
1042			  Setattr(nn, "previousSibling", last_unodes);
1043			  Setattr(last_unodes, "nextSibling", nn);
1044			  Setattr(nn, "sym:previousSibling", last_unodes);
1045			  Setattr(last_unodes, "sym:nextSibling", nn);
1046			  Setattr(nn, "sym:overloaded", unodes);
1047			  Setattr(unodes, "sym:overloaded", unodes);
1048			  last_unodes = nn;
1049			}
1050		      } else {
1051			Delete(nn);
1052		      }
1053		    }
1054		  }
1055		}
1056		c = Getattr(c, "csym:nextSibling");
1057	      }
1058	      if (unodes) {
1059		set_firstChild(n, unodes);
1060		if (ccount > 1) {
1061		  if (!Getattr(n, "sym:overloaded")) {
1062		    Setattr(n, "sym:overloaded", n);
1063		    Setattr(n, "sym:overname", "_SWIG_0");
1064		  }
1065		}
1066	      }
1067
1068	      /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
1069	       * list of overloaded methods we have just added in as child nodes to the "using" node.
1070	       * The node will still exist, it is just the symbol table linked list of overloaded methods
1071	       * which is hacked. */
1072	      if (Getattr(n, "sym:overloaded"))
1073	      {
1074		int cnt = 0;
1075#ifdef DEBUG_OVERLOADED
1076		Node *debugnode = n;
1077		show_overloaded(n);
1078#endif
1079		if (!firstChild(n)) {
1080		  // Remove from overloaded list ('using' node does not actually end up adding in any methods)
1081		  Node *ps = Getattr(n, "sym:previousSibling");
1082		  Node *ns = Getattr(n, "sym:nextSibling");
1083		  if (ps) {
1084		    Setattr(ps, "sym:nextSibling", ns);
1085		  }
1086		  if (ns) {
1087		    Setattr(ns, "sym:previousSibling", ps);
1088		  }
1089		} else {
1090		  // The 'using' node results in methods being added in - slot in the these methods here 
1091		  Node *ps = Getattr(n, "sym:previousSibling");
1092		  Node *ns = Getattr(n, "sym:nextSibling");
1093		  Node *fc = firstChild(n);
1094		  Node *pp = fc;
1095
1096		  Node *firstoverloaded = Getattr(n, "sym:overloaded");
1097		  if (firstoverloaded == n) {
1098		    // This 'using' node we are cutting out was the first node in the overloaded list. 
1099		    // Change the first node in the list to its first sibling
1100		    Delattr(firstoverloaded, "sym:overloaded");
1101		    Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
1102		    firstoverloaded = fc;
1103		    while (nnn) {
1104		      Setattr(nnn, "sym:overloaded", firstoverloaded);
1105		      nnn = Getattr(nnn, "sym:nextSibling");
1106		    }
1107		  }
1108		  while (pp) {
1109		    Node *ppn = Getattr(pp, "sym:nextSibling");
1110		    Setattr(pp, "sym:overloaded", firstoverloaded);
1111		    Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
1112		    if (ppn)
1113		      pp = ppn;
1114		    else
1115		      break;
1116		  }
1117		  if (ps) {
1118		    Setattr(ps, "sym:nextSibling", fc);
1119		    Setattr(fc, "sym:previousSibling", ps);
1120		  }
1121		  if (ns) {
1122		    Setattr(ns, "sym:previousSibling", pp);
1123		    Setattr(pp, "sym:nextSibling", ns);
1124		  }
1125#ifdef DEBUG_OVERLOADED
1126		  debugnode = firstoverloaded;
1127#endif
1128		}
1129		Delattr(n, "sym:previousSibling");
1130		Delattr(n, "sym:nextSibling");
1131		Delattr(n, "sym:overloaded");
1132		Delattr(n, "sym:overname");
1133#ifdef DEBUG_OVERLOADED
1134		show_overloaded(debugnode);
1135#endif
1136		clean_overloaded(n); // Needed?
1137	      }
1138	    }
1139	  }
1140	} else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
1141	  /* We install the using class name as kind of a typedef back to the original class */
1142	  String *uname = Getattr(n, "uname");
1143	  /* Import into current type scope */
1144	  SwigType_typedef_using(uname);
1145	} else if (Strcmp(ntype, "enum") == 0) {
1146	  SwigType_typedef_using(Getattr(n, "uname"));
1147	}
1148      }
1149    }
1150    return SWIG_OK;
1151  }
1152
1153  /* ------------------------------------------------------------
1154   * typemapDirective()
1155   * ------------------------------------------------------------ */
1156
1157  virtual int typemapDirective(Node *n) {
1158    if (inclass || nsname) {
1159      Node *items = firstChild(n);
1160      while (items) {
1161	Parm *pattern = Getattr(items, "pattern");
1162	Parm *parms = Getattr(items, "parms");
1163	normalize_later(pattern);
1164	normalize_later(parms);
1165	items = nextSibling(items);
1166      }
1167    }
1168    return SWIG_OK;
1169  }
1170
1171
1172  /* ------------------------------------------------------------
1173   * typemapcopyDirective()
1174   * ------------------------------------------------------------ */
1175
1176  virtual int typemapcopyDirective(Node *n) {
1177    if (inclass || nsname) {
1178      Node *items = firstChild(n);
1179      ParmList *pattern = Getattr(n, "pattern");
1180      normalize_later(pattern);
1181      while (items) {
1182	ParmList *npattern = Getattr(items, "pattern");
1183	normalize_later(npattern);
1184	items = nextSibling(items);
1185      }
1186    }
1187    return SWIG_OK;
1188  }
1189
1190  /* ------------------------------------------------------------
1191   * applyDirective()
1192   * ------------------------------------------------------------ */
1193
1194  virtual int applyDirective(Node *n) {
1195    if (inclass || nsname) {
1196      ParmList *pattern = Getattr(n, "pattern");
1197      normalize_later(pattern);
1198      Node *items = firstChild(n);
1199      while (items) {
1200	Parm *apattern = Getattr(items, "pattern");
1201	normalize_later(apattern);
1202	items = nextSibling(items);
1203      }
1204    }
1205    return SWIG_OK;
1206  }
1207
1208  /* ------------------------------------------------------------
1209   * clearDirective()
1210   * ------------------------------------------------------------ */
1211
1212  virtual int clearDirective(Node *n) {
1213    if (inclass || nsname) {
1214      Node *p;
1215      for (p = firstChild(n); p; p = nextSibling(p)) {
1216	ParmList *pattern = Getattr(p, "pattern");
1217	normalize_later(pattern);
1218      }
1219    }
1220    return SWIG_OK;
1221  }
1222
1223public:
1224  static void pass(Node *n) {
1225    TypePass t;
1226    t.top(n);
1227  }
1228};
1229
1230void Swig_process_types(Node *n) {
1231  if (!n)
1232    return;
1233  TypePass::pass(n);
1234}