1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * typesys.c
6 *
7 * SWIG type system management.   These functions are used to manage
8 * the C++ type system including typenames, typedef, type scopes,
9 * inheritance, and namespaces.   Generation of support code for the
10 * run-time type checker is also handled here.
11 * ----------------------------------------------------------------------------- */
12
13char cvsroot_typesys_c[] = "$Id: typesys.c 11097 2009-01-30 10:27:37Z bhy $";
14
15#include "swig.h"
16#include "cparse.h"
17
18/* -----------------------------------------------------------------------------
19 * Synopsis
20 *
21 * The purpose of this module is to manage type names and scoping issues related
22 * to the C++ type system.   The primary use is tracking typenames through typedef
23 * and inheritance.
24 *
25 * New typenames are introduced by typedef, class, and enum declarations.
26 * Each type is declared in a scope.  This is either the global scope, a
27 * class, or a namespace.  For example:
28 *
29 *  typedef int A;         // Typename A, in global scope
30 *  namespace Foo {
31 *    typedef int A;       // Typename A, in scope Foo::
32 *  }
33 *  class Bar {            // Typename Bar, in global scope
34 *    typedef int A;       // Typename A, in scope Bar::
35 *  }
36 *
37 * To manage scopes, the type system is constructed as a tree of hash tables.  Each
38 * hash table contains the following attributes:
39 *
40 *    "name"            -  Scope name
41 *    "qname"           -  Fully qualified typename
42 *    "typetab"         -  Type table containing typenames and typedef information
43 *    "symtab"          -  Hash table of symbols defined in a scope
44 *    "inherit"         -  List of inherited scopes
45 *    "parent"          -  Parent scope
46 *
47 * Typedef information is stored in the "typetab" hash table.  For example,
48 * if you have these declarations:
49 *
50 *      typedef int A;
51 *      typedef A B;
52 *      typedef B *C;
53 *
54 * typetab is built as follows:
55 *
56 *      "A"     : "int"
57 *      "B"     : "A"
58 *      "C"     : "p.B"
59 *
60 * To resolve a type back to its root type, one repeatedly expands on the type base.
61 * For example:
62 *
63 *     C *[40]   ---> a(40).p.C       (string type representation, see stype.c)
64 *               ---> a(40).p.p.B     (C --> p.B)
65 *               ---> a(40).p.p.A     (B --> A)
66 *               ---> a(40).p.p.int   (A --> int)
67 *
68 * For inheritance, SWIG tries to resolve types back to the base class. For instance, if
69 * you have this:
70 *
71 *     class Foo {
72 *     public:
73 *        typedef int Integer;
74 *     };
75 *
76 *     class Bar : public Foo {
77 *           void blah(Integer x);
78 *     }
79 *
80 * The argument type of Bar::blah will be set to Foo::Integer.
81 *
82 * The scope-inheritance mechanism is used to manage C++ namespace aliases.
83 * For example, if you have this:
84 *
85 *    namespace Foo {
86 *         typedef int Integer;
87 *    }
88 *
89 *   namespace F = Foo;
90 *
91 * In this case, "F::" is defined as a scope that "inherits" from Foo.  Internally,
92 * "F::" will merely be an empty scope that refers to Foo.  SWIG will never
93 * place new type information into a namespace alias---attempts to do so
94 * will generate a warning message (in the parser) and will place information into
95 * Foo instead.
96 *
97 *----------------------------------------------------------------------------- */
98
99static Typetab *current_scope = 0;	/* Current type scope                           */
100static Hash *current_typetab = 0;	/* Current type table                           */
101static Hash *current_symtab = 0;	/* Current symbol table                         */
102static Typetab *global_scope = 0;	/* The global scope                             */
103static Hash *scopes = 0;	/* Hash table containing fully qualified scopes */
104
105/* Performance optimization */
106#define SWIG_TYPEDEF_RESOLVE_CACHE
107static Hash *typedef_resolve_cache = 0;
108static Hash *typedef_all_cache = 0;
109static Hash *typedef_qualified_cache = 0;
110
111static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix);
112
113/* common attribute keys, to avoid calling find_key all the times */
114
115/*
116   Enable this one if your language fully support SwigValueWrapper<T>.
117
118   Leaving at '0' keeps the old swig behavior, which is not
119   always safe, but is well known.
120
121   Setting at '1' activates the new scheme, which is always safe but
122   it requires all the typemaps to be ready for that.
123
124*/
125static int value_wrapper_mode = 0;
126int Swig_value_wrapper_mode(int mode) {
127  value_wrapper_mode = mode;
128  return mode;
129}
130
131
132static void flush_cache() {
133  typedef_resolve_cache = 0;
134  typedef_all_cache = 0;
135  typedef_qualified_cache = 0;
136}
137
138/* Initialize the scoping system */
139
140void SwigType_typesystem_init() {
141  if (global_scope)
142    Delete(global_scope);
143  if (scopes)
144    Delete(scopes);
145
146  current_scope = NewHash();
147  global_scope = current_scope;
148
149  Setattr(current_scope, "name", "");	/* No name for global scope */
150  current_typetab = NewHash();
151  Setattr(current_scope, "typetab", current_typetab);
152
153  current_symtab = 0;
154  scopes = NewHash();
155  Setattr(scopes, "", current_scope);
156}
157
158
159/* -----------------------------------------------------------------------------
160 * SwigType_typedef()
161 *
162 * Defines a new typedef in the current scope. Returns -1 if the type name is
163 * already defined.
164 * ----------------------------------------------------------------------------- */
165
166int SwigType_typedef(SwigType *type, const_String_or_char_ptr name) {
167  if (Getattr(current_typetab, name))
168    return -1;			/* Already defined */
169  if (Strcmp(type, name) == 0) {	/* Can't typedef a name to itself */
170    return 0;
171  }
172
173  /* Check if 'type' is already a scope.  If so, we create an alias in the type
174     system for it.  This is needed to make strange nested scoping problems work
175     correctly.  */
176  {
177    Typetab *t = SwigType_find_scope(current_scope, type);
178    if (t) {
179      SwigType_new_scope(name);
180      SwigType_inherit_scope(t);
181      SwigType_pop_scope();
182    }
183  }
184  Setattr(current_typetab, name, type);
185  flush_cache();
186  return 0;
187}
188
189
190/* -----------------------------------------------------------------------------
191 * SwigType_typedef_class()
192 *
193 * Defines a class in the current scope.
194 * ----------------------------------------------------------------------------- */
195
196int SwigType_typedef_class(const_String_or_char_ptr name) {
197  String *cname;
198  /*  Printf(stdout,"class : '%s'\n", name); */
199  if (Getattr(current_typetab, name))
200    return -1;			/* Already defined */
201  cname = NewString(name);
202  Setmeta(cname, "class", "1");
203  Setattr(current_typetab, cname, cname);
204  Delete(cname);
205  flush_cache();
206  return 0;
207}
208
209/* -----------------------------------------------------------------------------
210 * SwigType_scope_name()
211 *
212 * Returns the qualified scope name of a type table
213 * ----------------------------------------------------------------------------- */
214
215String *SwigType_scope_name(Typetab *ttab) {
216  String *qname = NewString(Getattr(ttab, "name"));
217  ttab = Getattr(ttab, "parent");
218  while (ttab) {
219    String *pname = Getattr(ttab, "name");
220    if (Len(pname)) {
221      Insert(qname, 0, "::");
222      Insert(qname, 0, pname);
223    }
224    ttab = Getattr(ttab, "parent");
225  }
226  return qname;
227}
228
229/* -----------------------------------------------------------------------------
230 * SwigType_new_scope()
231 *
232 * Creates a new scope
233 * ----------------------------------------------------------------------------- */
234
235void SwigType_new_scope(const_String_or_char_ptr name) {
236  Typetab *s;
237  Hash *ttab;
238  String *qname;
239
240  if (!name) {
241    name = "<unnamed>";
242  }
243  s = NewHash();
244  Setattr(s, "name", name);
245  Setattr(s, "parent", current_scope);
246  ttab = NewHash();
247  Setattr(s, "typetab", ttab);
248
249  /* Build fully qualified name and */
250  qname = SwigType_scope_name(s);
251  Setattr(scopes, qname, s);
252  Setattr(s, "qname", qname);
253  Delete(qname);
254
255  current_scope = s;
256  current_typetab = ttab;
257  current_symtab = 0;
258  flush_cache();
259}
260
261/* -----------------------------------------------------------------------------
262 * SwigType_inherit_scope()
263 *
264 * Makes the current scope inherit from another scope.  This is used for both
265 * C++ class inheritance, namespaces, and namespace aliases.
266 * ----------------------------------------------------------------------------- */
267
268void SwigType_inherit_scope(Typetab *scope) {
269  List *inherits;
270  int i, len;
271  inherits = Getattr(current_scope, "inherit");
272  if (!inherits) {
273    inherits = NewList();
274    Setattr(current_scope, "inherit", inherits);
275    Delete(inherits);
276  }
277  assert(scope != current_scope);
278
279  len = Len(inherits);
280  for (i = 0; i < len; i++) {
281    Node *n = Getitem(inherits, i);
282    if (n == scope)
283      return;
284  }
285  Append(inherits, scope);
286}
287
288/* -----------------------------------------------------------------------------
289 * SwigType_scope_alias()
290 *
291 * Creates a scope-alias.
292 * ----------------------------------------------------------------------------- */
293
294void SwigType_scope_alias(String *aliasname, Typetab *ttab) {
295  String *q;
296  /*  Printf(stdout,"alias: '%s' '%x'\n", aliasname, ttab); */
297  q = SwigType_scope_name(current_scope);
298  if (Len(q)) {
299    Append(q, "::");
300  }
301  Append(q, aliasname);
302  Setattr(scopes, q, ttab);
303  flush_cache();
304}
305
306/* -----------------------------------------------------------------------------
307 * SwigType_using_scope()
308 *
309 * Import another scope into this scope.
310 * ----------------------------------------------------------------------------- */
311
312void SwigType_using_scope(Typetab *scope) {
313  SwigType_inherit_scope(scope);
314  {
315    List *ulist;
316    int i, len;
317    ulist = Getattr(current_scope, "using");
318    if (!ulist) {
319      ulist = NewList();
320      Setattr(current_scope, "using", ulist);
321      Delete(ulist);
322    }
323    assert(scope != current_scope);
324    len = Len(ulist);
325    for (i = 0; i < len; i++) {
326      Typetab *n = Getitem(ulist, i);
327      if (n == scope)
328	return;
329    }
330    Append(ulist, scope);
331  }
332  flush_cache();
333}
334
335/* -----------------------------------------------------------------------------
336 * SwigType_pop_scope()
337 *
338 * Pop off the last scope and perform a merge operation.  Returns the hash
339 * table for the scope that was popped off.
340 * ----------------------------------------------------------------------------- */
341
342Typetab *SwigType_pop_scope() {
343  Typetab *t, *old = current_scope;
344  t = Getattr(current_scope, "parent");
345  if (!t)
346    t = global_scope;
347  current_scope = t;
348  current_typetab = Getattr(t, "typetab");
349  current_symtab = Getattr(t, "symtab");
350  flush_cache();
351  return old;
352}
353
354/* -----------------------------------------------------------------------------
355 * SwigType_set_scope()
356 *
357 * Set the scope.  Returns the old scope.
358 * ----------------------------------------------------------------------------- */
359
360Typetab *SwigType_set_scope(Typetab *t) {
361  Typetab *old = current_scope;
362  if (!t)
363    t = global_scope;
364  current_scope = t;
365  current_typetab = Getattr(t, "typetab");
366  current_symtab = Getattr(t, "symtab");
367  flush_cache();
368  return old;
369}
370
371/* -----------------------------------------------------------------------------
372 * SwigType_attach_symtab()
373 *
374 * Attaches a symbol table to a type scope
375 * ----------------------------------------------------------------------------- */
376
377void SwigType_attach_symtab(Symtab *sym) {
378  Setattr(current_scope, "symtab", sym);
379  current_symtab = sym;
380}
381
382/* -----------------------------------------------------------------------------
383 * SwigType_print_scope()
384 *
385 * Debugging function for printing out current scope
386 * ----------------------------------------------------------------------------- */
387
388void SwigType_print_scope(Typetab *t) {
389  Hash *ttab;
390  Iterator i, j;
391
392  for (i = First(scopes); i.key; i = Next(i)) {
393    t = i.item;
394    ttab = Getattr(i.item, "typetab");
395
396    Printf(stdout, "Type scope '%s' (%x)\n", i.key, i.item);
397    {
398      List *inherit = Getattr(i.item, "inherit");
399      if (inherit) {
400	Iterator j;
401	for (j = First(inherit); j.item; j = Next(j)) {
402	  Printf(stdout, "    Inherits from '%s' (%x)\n", Getattr(j.item, "qname"), j.item);
403	}
404      }
405    }
406    Printf(stdout, "-------------------------------------------------------------\n");
407    for (j = First(ttab); j.key; j = Next(j)) {
408      Printf(stdout, "%40s -> %s\n", j.key, j.item);
409    }
410  }
411}
412
413static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) {
414  Typetab *ss;
415  String *nnameprefix = 0;
416  static int check_parent = 1;
417
418  /*  Printf(stdout,"find_scope: %x(%s) '%s'\n", s, Getattr(s,"name"), nameprefix); */
419
420  if (SwigType_istemplate(nameprefix)) {
421    nnameprefix = SwigType_typedef_resolve_all(nameprefix);
422    nameprefix = nnameprefix;
423  }
424
425  ss = s;
426  while (ss) {
427    String *full;
428    String *qname = Getattr(ss, "qname");
429    if (qname) {
430      full = NewStringf("%s::%s", qname, nameprefix);
431    } else {
432      full = NewString(nameprefix);
433    }
434    if (Getattr(scopes, full)) {
435      s = Getattr(scopes, full);
436    } else {
437      s = 0;
438    }
439    Delete(full);
440    if (s) {
441      if (nnameprefix)
442	Delete(nnameprefix);
443      return s;
444    }
445    if (!s) {
446      /* Check inheritance */
447      List *inherit;
448      inherit = Getattr(ss, "using");
449      if (inherit) {
450	Typetab *ttab;
451	int i, len;
452	len = Len(inherit);
453	for (i = 0; i < len; i++) {
454	  int oldcp = check_parent;
455	  ttab = Getitem(inherit, i);
456	  check_parent = 0;
457	  s = SwigType_find_scope(ttab, nameprefix);
458	  check_parent = oldcp;
459	  if (s) {
460	    if (nnameprefix)
461	      Delete(nnameprefix);
462	    return s;
463	  }
464	}
465      }
466    }
467    if (!check_parent)
468      break;
469    ss = Getattr(ss, "parent");
470  }
471  if (nnameprefix)
472    Delete(nnameprefix);
473  return 0;
474}
475
476/* -----------------------------------------------------------------------------
477 * typedef_resolve()
478 *
479 * Resolves a typedef and returns a new type string.  Returns 0 if there is no
480 * typedef mapping.  base is a name without qualification.
481 * Internal function.
482 * ----------------------------------------------------------------------------- */
483
484static Typetab *resolved_scope = 0;
485
486/* Internal function */
487
488static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) {
489  Hash *ttab;
490  SwigType *type = 0;
491  List *inherit;
492  Typetab *parent;
493
494  /* if (!s) return 0; *//* now is checked bellow */
495  /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base);  */
496
497  if (!Getmark(s)) {
498    Setmark(s, 1);
499
500    ttab = Getattr(s, "typetab");
501    type = Getattr(ttab, base);
502    if (type) {
503      resolved_scope = s;
504      Setmark(s, 0);
505    } else {
506      /* Hmmm. Not found in my scope.  It could be in an inherited scope */
507      inherit = Getattr(s, "inherit");
508      if (inherit) {
509	int i, len;
510	len = Len(inherit);
511	for (i = 0; i < len; i++) {
512	  type = _typedef_resolve(Getitem(inherit, i), base, 0);
513	  if (type) {
514	    Setmark(s, 0);
515	    break;
516	  }
517	}
518      }
519      if (!type) {
520	/* Hmmm. Not found in my scope.  check parent */
521	if (look_parent) {
522	  parent = Getattr(s, "parent");
523	  type = parent ? _typedef_resolve(parent, base, 1) : 0;
524	}
525      }
526      Setmark(s, 0);
527    }
528  }
529  return type;
530}
531
532static SwigType *typedef_resolve(Typetab *s, String *base) {
533  return _typedef_resolve(s, base, 1);
534}
535
536
537/* -----------------------------------------------------------------------------
538 * SwigType_typedef_resolve()
539 * ----------------------------------------------------------------------------- */
540
541/* #define SWIG_DEBUG */
542SwigType *SwigType_typedef_resolve(const SwigType *t) {
543  String *base;
544  String *type = 0;
545  String *r = 0;
546  Typetab *s;
547  Hash *ttab;
548  String *namebase = 0;
549  String *nameprefix = 0;
550  int newtype = 0;
551
552  /*
553     if (!noscope) {
554     noscope = NewStringEmpty();
555     }
556   */
557
558  resolved_scope = 0;
559
560#ifdef SWIG_TYPEDEF_RESOLVE_CACHE
561  if (!typedef_resolve_cache) {
562    typedef_resolve_cache = NewHash();
563  }
564  r = Getattr(typedef_resolve_cache, t);
565  if (r) {
566    resolved_scope = Getmeta(r, "scope");
567    return Copy(r);
568  }
569#endif
570
571  base = SwigType_base(t);
572
573#ifdef SWIG_DEBUG
574  Printf(stdout, "base = '%s' t='%s'\n", base, t);
575#endif
576
577  if (SwigType_issimple(base)) {
578    s = current_scope;
579    ttab = current_typetab;
580    if (strncmp(Char(base), "::", 2) == 0) {
581      s = global_scope;
582      ttab = Getattr(s, "typetab");
583      Delitem(base, 0);
584      Delitem(base, 0);
585    }
586    /* Do a quick check in the local scope */
587    type = Getattr(ttab, base);
588    if (type) {
589      resolved_scope = s;
590    }
591    if (!type) {
592      /* Didn't find in this scope.   We need to do a little more searching */
593      if (Swig_scopename_check(base)) {
594	/* A qualified name. */
595	Swig_scopename_split(base, &nameprefix, &namebase);
596#ifdef SWIG_DEBUG
597	Printf(stdout, "nameprefix = '%s'\n", nameprefix);
598#endif
599	if (nameprefix) {
600	  /* Name had a prefix on it.   See if we can locate the proper scope for it */
601	  s = SwigType_find_scope(s, nameprefix);
602
603	  /* Couldn't locate a scope for the type.  */
604	  if (!s) {
605	    Delete(base);
606	    Delete(namebase);
607	    Delete(nameprefix);
608	    r = 0;
609	    goto return_result;
610	  }
611	  /* Try to locate the name starting in the scope */
612#ifdef SWIG_DEBUG
613	  Printf(stdout, "namebase = '%s'\n", namebase);
614#endif
615	  type = typedef_resolve(s, namebase);
616	  if (type) {
617	    /* we need to look for the resolved type, this will also
618	       fix the resolved_scope if 'type' and 'namebase' are
619	       declared in different scopes */
620	    String *rtype = 0;
621	    rtype = typedef_resolve(resolved_scope, type);
622	    if (rtype)
623	      type = rtype;
624	  }
625#ifdef SWIG_DEBUG
626	  Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type);
627#endif
628	  if ((type) && (!Swig_scopename_check(type)) && resolved_scope) {
629	    Typetab *rtab = resolved_scope;
630	    String *qname = Getattr(resolved_scope, "qname");
631	    /* If qualified *and* the typename is defined from the resolved scope, we qualify */
632	    if ((qname) && typedef_resolve(resolved_scope, type)) {
633	      type = Copy(type);
634	      Insert(type, 0, "::");
635	      Insert(type, 0, qname);
636#ifdef SWIG_DEBUG
637	      Printf(stdout, "qual %s \n", type);
638#endif
639	      newtype = 1;
640	    }
641	    resolved_scope = rtab;
642	  }
643	} else {
644	  /* Name is unqualified. */
645	  type = typedef_resolve(s, base);
646	}
647      } else {
648	/* Name is unqualified. */
649	type = typedef_resolve(s, base);
650      }
651    }
652
653    if (type && (Equal(base, type))) {
654      if (newtype)
655	Delete(type);
656      Delete(base);
657      Delete(namebase);
658      Delete(nameprefix);
659      r = 0;
660      goto return_result;
661    }
662
663    /* If the type is a template, and no typedef was found, we need to check the
664       template arguments one by one to see if they can be resolved. */
665
666    if (!type && SwigType_istemplate(base)) {
667      List *tparms;
668      String *suffix;
669      int i, sz;
670      int rep = 0;
671      type = SwigType_templateprefix(base);
672      newtype = 1;
673      suffix = SwigType_templatesuffix(base);
674      Append(type, "<(");
675      tparms = SwigType_parmlist(base);
676      sz = Len(tparms);
677      for (i = 0; i < sz; i++) {
678	SwigType *tpr;
679	SwigType *tp = Getitem(tparms, i);
680	if (!rep) {
681	  tpr = SwigType_typedef_resolve(tp);
682	} else {
683	  tpr = 0;
684	}
685	if (tpr) {
686	  Append(type, tpr);
687	  Delete(tpr);
688	  rep = 1;
689	} else {
690	  Append(type, tp);
691	}
692	if ((i + 1) < sz)
693	  Append(type, ",");
694      }
695      Append(type, ")>");
696      Append(type, suffix);
697      Delete(suffix);
698      Delete(tparms);
699      if (!rep) {
700	Delete(type);
701	type = 0;
702      }
703    }
704    if (namebase)
705      Delete(namebase);
706    if (nameprefix)
707      Delete(nameprefix);
708  } else {
709    if (SwigType_isfunction(base)) {
710      List *parms;
711      int i, sz;
712      int rep = 0;
713      type = NewString("f(");
714      newtype = 1;
715      parms = SwigType_parmlist(base);
716      sz = Len(parms);
717      for (i = 0; i < sz; i++) {
718	SwigType *tpr;
719	SwigType *tp = Getitem(parms, i);
720	if (!rep) {
721	  tpr = SwigType_typedef_resolve(tp);
722	} else {
723	  tpr = 0;
724	}
725	if (tpr) {
726	  Append(type, tpr);
727	  Delete(tpr);
728	  rep = 1;
729	} else {
730	  Append(type, tp);
731	}
732	if ((i + 1) < sz)
733	  Append(type, ",");
734      }
735      Append(type, ").");
736      Delete(parms);
737      if (!rep) {
738	Delete(type);
739	type = 0;
740      }
741    } else if (SwigType_ismemberpointer(base)) {
742      String *rt;
743      String *mtype = SwigType_parm(base);
744      rt = SwigType_typedef_resolve(mtype);
745      if (rt) {
746	type = NewStringf("m(%s).", rt);
747	newtype = 1;
748	Delete(rt);
749      }
750      Delete(mtype);
751    } else {
752      type = 0;
753    }
754  }
755  r = SwigType_prefix(t);
756  if (!type) {
757    if (r && Len(r)) {
758      char *cr = Char(r);
759      if ((strstr(cr, "f(") || (strstr(cr, "m(")))) {
760	SwigType *rt = SwigType_typedef_resolve(r);
761	if (rt) {
762	  Delete(r);
763	  Append(rt, base);
764	  Delete(base);
765	  r = rt;
766	  goto return_result;
767	}
768      }
769    }
770    Delete(r);
771    Delete(base);
772    r = 0;
773    goto return_result;
774  }
775  Delete(base);
776  Append(r, type);
777  if (newtype) {
778    Delete(type);
779  }
780
781return_result:
782#ifdef SWIG_TYPEDEF_RESOLVE_CACHE
783  {
784    String *key = NewString(t);
785    if (r) {
786      SwigType *r1;
787      Setattr(typedef_resolve_cache, key, r);
788      Setmeta(r, "scope", resolved_scope);
789      r1 = Copy(r);
790      Delete(r);
791      r = r1;
792    }
793    Delete(key);
794  }
795#endif
796  return r;
797}
798
799/* -----------------------------------------------------------------------------
800 * SwigType_typedef_resolve_all()
801 *
802 * Fully resolve a type down to its most basic datatype
803 * ----------------------------------------------------------------------------- */
804
805SwigType *SwigType_typedef_resolve_all(SwigType *t) {
806  SwigType *n;
807  SwigType *r;
808
809  /* Check to see if the typedef resolve has been done before by checking the cache */
810  if (!typedef_all_cache) {
811    typedef_all_cache = NewHash();
812  }
813  r = Getattr(typedef_all_cache, t);
814  if (r) {
815    return Copy(r);
816  }
817
818  /* Recursively resolve the typedef */
819  r = NewString(t);
820  while ((n = SwigType_typedef_resolve(r))) {
821    Delete(r);
822    r = n;
823  }
824
825  /* Add the typedef to the cache for next time it is looked up */
826  {
827    String *key;
828    SwigType *rr = Copy(r);
829    key = NewString(t);
830    Setattr(typedef_all_cache, key, rr);
831    Delete(key);
832    Delete(rr);
833  }
834  return r;
835}
836
837
838/* -----------------------------------------------------------------------------
839 * SwigType_typedef_qualified()
840 *
841 * Given a type declaration, this function tries to fully qualify it according to
842 * typedef scope rules.
843 * Inconsistency to be fixed: ::Foo returns ::Foo, whereas ::Foo * returns Foo *
844 * ----------------------------------------------------------------------------- */
845
846SwigType *SwigType_typedef_qualified(SwigType *t) {
847  List *elements;
848  String *result;
849  int i, len;
850
851  if (strncmp(Char(t), "::", 2) == 0) {
852    return Copy(t);
853  }
854
855  if (!typedef_qualified_cache)
856    typedef_qualified_cache = NewHash();
857  result = Getattr(typedef_qualified_cache, t);
858  if (result) {
859    String *rc = Copy(result);
860    return rc;
861  }
862
863  result = NewStringEmpty();
864  elements = SwigType_split(t);
865  len = Len(elements);
866  for (i = 0; i < len; i++) {
867    String *ty = 0;
868    String *e = Getitem(elements, i);
869    if (SwigType_issimple(e)) {
870      if (!SwigType_istemplate(e)) {
871	String *isenum = 0;
872	if (SwigType_isenum(e)) {
873	  isenum = NewString("enum ");
874	  ty = NewString(Char(e) + 5);
875	  e = ty;
876	}
877	resolved_scope = 0;
878	if (typedef_resolve(current_scope, e)) {
879	  /* resolved_scope contains the scope that actually resolved the symbol */
880	  String *qname = Getattr(resolved_scope, "qname");
881	  if (qname) {
882	    Insert(e, 0, "::");
883	    Insert(e, 0, qname);
884	  }
885	} else {
886	  if (Swig_scopename_check(e)) {
887	    String *qlast;
888	    String *qname;
889	    Swig_scopename_split(e, &qname, &qlast);
890	    if (qname) {
891	      String *tqname = SwigType_typedef_qualified(qname);
892	      Clear(e);
893	      Printf(e, "%s::%s", tqname, qlast);
894	      Delete(qname);
895	      Delete(tqname);
896	    }
897	    Delete(qlast);
898
899	    /* Automatic template instantiation might go here??? */
900	  } else {
901	    /* It's a bare name.  It's entirely possible, that the
902	       name is part of a namespace. We'll check this by unrolling
903	       out of the current scope */
904
905	    Typetab *cs = current_scope;
906	    while (cs) {
907	      String *qs = SwigType_scope_name(cs);
908	      if (Len(qs)) {
909		Append(qs, "::");
910	      }
911	      Append(qs, e);
912	      if (Getattr(scopes, qs)) {
913		Clear(e);
914		Append(e, qs);
915		Delete(qs);
916		break;
917	      }
918	      Delete(qs);
919	      cs = Getattr(cs, "parent");
920	    }
921	  }
922	}
923	if (isenum) {
924	  Insert(e, 0, isenum);
925	  Delete(isenum);
926	}
927      } else {
928	/* Template.  We need to qualify template parameters as well as the template itself */
929	String *tprefix, *qprefix;
930	String *tsuffix;
931	Iterator pi;
932	Parm *p;
933	List *parms;
934	ty = Swig_symbol_template_deftype(e, current_symtab);
935	e = ty;
936	parms = SwigType_parmlist(e);
937	tprefix = SwigType_templateprefix(e);
938	tsuffix = SwigType_templatesuffix(e);
939	qprefix = SwigType_typedef_qualified(tprefix);
940	Append(qprefix, "<(");
941	pi = First(parms);
942	while ((p = pi.item)) {
943	  String *qt = SwigType_typedef_qualified(p);
944	  if (Equal(qt, p)) {	/*  && (!Swig_scopename_check(qt))) */
945	    /* No change in value.  It is entirely possible that the parameter is an integer value.
946	       If there is a symbol table associated with this scope, we're going to check for this */
947
948	    if (current_symtab) {
949	      Node *lastnode = 0;
950	      String *value = Copy(p);
951	      while (1) {
952		Node *n = Swig_symbol_clookup(value, current_symtab);
953		if (n == lastnode)
954		  break;
955		lastnode = n;
956		if (n) {
957		  char *ntype = Char(nodeType(n));
958		  if (strcmp(ntype, "enumitem") == 0) {
959		    /* An enum item.   Generate a fully qualified name */
960		    String *qn = Swig_symbol_qualified(n);
961		    if (Len(qn)) {
962		      Append(qn, "::");
963		      Append(qn, Getattr(n, "name"));
964		      Delete(value);
965		      value = qn;
966		      continue;
967		    } else {
968		      Delete(qn);
969		      break;
970		    }
971		  } else if ((strcmp(ntype, "cdecl") == 0) && (Getattr(n, "value"))) {
972		    Delete(value);
973		    value = Copy(Getattr(n, "value"));
974		    continue;
975		  }
976		}
977		break;
978	      }
979	      Append(qprefix, value);
980	      Delete(value);
981	    } else {
982	      Append(qprefix, p);
983	    }
984	  } else {
985	    Append(qprefix, qt);
986	  }
987	  Delete(qt);
988	  pi = Next(pi);
989	  if (pi.item) {
990	    Append(qprefix, ",");
991	  }
992	}
993	Append(qprefix, ")>");
994	Append(qprefix, tsuffix);
995	Delete(tsuffix);
996	Clear(e);
997	Append(e, qprefix);
998	Delete(tprefix);
999	Delete(qprefix);
1000	Delete(parms);
1001      }
1002      if (strncmp(Char(e), "::", 2) == 0) {
1003	Delitem(e, 0);
1004	Delitem(e, 0);
1005      }
1006      Append(result, e);
1007      Delete(ty);
1008    } else if (SwigType_isfunction(e)) {
1009      List *parms = SwigType_parmlist(e);
1010      String *s = NewString("f(");
1011      Iterator pi;
1012      pi = First(parms);
1013      while (pi.item) {
1014	String *pq = SwigType_typedef_qualified(pi.item);
1015	Append(s, pq);
1016	Delete(pq);
1017	pi = Next(pi);
1018	if (pi.item) {
1019	  Append(s, ",");
1020	}
1021      }
1022      Append(s, ").");
1023      Append(result, s);
1024      Delete(s);
1025      Delete(parms);
1026    } else if (SwigType_isarray(e)) {
1027      String *ndim;
1028      String *dim = SwigType_parm(e);
1029      ndim = Swig_symbol_string_qualify(dim, 0);
1030      Printf(result, "a(%s).", ndim);
1031      Delete(dim);
1032      Delete(ndim);
1033    } else {
1034      Append(result, e);
1035    }
1036  }
1037  Delete(elements);
1038  {
1039    String *key, *cresult;
1040    key = NewString(t);
1041    cresult = NewString(result);
1042    Setattr(typedef_qualified_cache, key, cresult);
1043    Delete(key);
1044    Delete(cresult);
1045  }
1046  return result;
1047}
1048
1049/* -----------------------------------------------------------------------------
1050 * SwigType_istypedef()
1051 *
1052 * Checks a typename to see if it is a typedef.
1053 * ----------------------------------------------------------------------------- */
1054
1055int SwigType_istypedef(SwigType *t) {
1056  String *type;
1057
1058  type = SwigType_typedef_resolve(t);
1059  if (type) {
1060    Delete(type);
1061    return 1;
1062  } else {
1063    return 0;
1064  }
1065}
1066
1067
1068/* -----------------------------------------------------------------------------
1069 * SwigType_typedef_using()
1070 *
1071 * Processes a 'using' declaration to import types from one scope into another.
1072 * Name is a qualified name like A::B.
1073 * ----------------------------------------------------------------------------- */
1074
1075int SwigType_typedef_using(const_String_or_char_ptr name) {
1076  String *base;
1077  String *td;
1078  String *prefix;
1079  Typetab *s;
1080  Typetab *tt = 0;
1081
1082  String *defined_name = 0;
1083
1084  /*  Printf(stdout,"using %s\n", name); */
1085
1086  if (!Swig_scopename_check(name))
1087    return -1;			/* Not properly qualified */
1088  base = Swig_scopename_last(name);
1089
1090  /* See if the base is already defined in this scope */
1091  if (Getattr(current_typetab, base)) {
1092    Delete(base);
1093    return -1;
1094  }
1095
1096  /* See if the using name is a scope */
1097  /*  tt = SwigType_find_scope(current_scope,name);
1098     Printf(stdout,"tt = %x, name = '%s'\n", tt, name); */
1099
1100  /* We set up a typedef  B --> A::B */
1101  Setattr(current_typetab, base, name);
1102
1103  /* Find the scope name where the symbol is defined */
1104  td = SwigType_typedef_resolve(name);
1105  /*  Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */
1106  if (resolved_scope) {
1107    defined_name = Getattr(resolved_scope, "qname");
1108    if (defined_name) {
1109      defined_name = Copy(defined_name);
1110      Append(defined_name, "::");
1111      Append(defined_name, base);
1112      /*  Printf(stdout,"defined_name = '%s'\n", defined_name); */
1113      tt = SwigType_find_scope(current_scope, defined_name);
1114    }
1115  }
1116  if (td)
1117    Delete(td);
1118
1119
1120  /* Figure out the scope the using directive refers to */
1121  {
1122    prefix = Swig_scopename_prefix(name);
1123    s = SwigType_find_scope(current_scope, prefix);
1124    if (s) {
1125      Hash *ttab = Getattr(s, "typetab");
1126      if (!Getattr(ttab, base) && defined_name) {
1127	Setattr(ttab, base, defined_name);
1128      }
1129    }
1130  }
1131
1132  if (tt) {
1133    /* Using directive had its own scope.  We need to create a new scope for it */
1134    SwigType_new_scope(base);
1135    SwigType_inherit_scope(tt);
1136    SwigType_pop_scope();
1137  }
1138
1139  if (defined_name)
1140    Delete(defined_name);
1141  Delete(prefix);
1142  Delete(base);
1143  return 0;
1144}
1145
1146/* -----------------------------------------------------------------------------
1147 * SwigType_isclass()
1148 *
1149 * Determines if a type defines a class or not.   A class is defined by
1150 * its type-table entry maps to itself.  Note: a pointer to a class is not
1151 * a class.
1152 * ----------------------------------------------------------------------------- */
1153
1154int SwigType_isclass(SwigType *t) {
1155  SwigType *qty, *qtys;
1156  int isclass = 0;
1157
1158  qty = SwigType_typedef_resolve_all(t);
1159  qtys = SwigType_strip_qualifiers(qty);
1160  if (SwigType_issimple(qtys)) {
1161    String *td = SwigType_typedef_resolve(qtys);
1162    if (td) {
1163      Delete(td);
1164    }
1165    if (resolved_scope) {
1166      isclass = 1;
1167    }
1168    /* Hmmm. Not a class.  If a template, it might be uninstantiated */
1169    if (!isclass && SwigType_istemplate(qtys)) {
1170      String *tp = SwigType_templateprefix(qtys);
1171      if (Strcmp(tp, t) != 0) {
1172	isclass = SwigType_isclass(tp);
1173      }
1174      Delete(tp);
1175    }
1176  }
1177  Delete(qty);
1178  Delete(qtys);
1179  return isclass;
1180}
1181
1182/* -----------------------------------------------------------------------------
1183 * SwigType_type()
1184 *
1185 * Returns an integer code describing the datatype.  This is only used for
1186 * compatibility with SWIG1.1 language modules and is likely to go away once
1187 * everything is based on typemaps.
1188 * ----------------------------------------------------------------------------- */
1189
1190int SwigType_type(SwigType *t) {
1191  char *c;
1192  /* Check for the obvious stuff */
1193  c = Char(t);
1194
1195  if (strncmp(c, "p.", 2) == 0) {
1196    if (SwigType_type(c + 2) == T_CHAR)
1197      return T_STRING;
1198    else
1199      return T_POINTER;
1200  }
1201  if (strncmp(c, "a(", 2) == 0)
1202    return T_ARRAY;
1203  if (strncmp(c, "r.", 2) == 0)
1204    return T_REFERENCE;
1205  if (strncmp(c, "m(", 2) == 0)
1206    return T_MPOINTER;
1207  if (strncmp(c, "q(", 2) == 0) {
1208    while (*c && (*c != '.'))
1209      c++;
1210    if (*c)
1211      return SwigType_type(c + 1);
1212    return T_ERROR;
1213  }
1214  if (strncmp(c, "f(", 2) == 0)
1215    return T_FUNCTION;
1216
1217  /* Look for basic types */
1218  if (strcmp(c, "int") == 0)
1219    return T_INT;
1220  if (strcmp(c, "long") == 0)
1221    return T_LONG;
1222  if (strcmp(c, "short") == 0)
1223    return T_SHORT;
1224  if (strcmp(c, "unsigned") == 0)
1225    return T_UINT;
1226  if (strcmp(c, "unsigned short") == 0)
1227    return T_USHORT;
1228  if (strcmp(c, "unsigned long") == 0)
1229    return T_ULONG;
1230  if (strcmp(c, "unsigned int") == 0)
1231    return T_UINT;
1232  if (strcmp(c, "char") == 0)
1233    return T_CHAR;
1234  if (strcmp(c, "signed char") == 0)
1235    return T_SCHAR;
1236  if (strcmp(c, "unsigned char") == 0)
1237    return T_UCHAR;
1238  if (strcmp(c, "float") == 0)
1239    return T_FLOAT;
1240  if (strcmp(c, "double") == 0)
1241    return T_DOUBLE;
1242  if (strcmp(c, "long double") == 0)
1243    return T_LONGDOUBLE;
1244  if (!cparse_cplusplus && (strcmp(c, "float complex") == 0))
1245    return T_FLTCPLX;
1246  if (!cparse_cplusplus && (strcmp(c, "double complex") == 0))
1247    return T_DBLCPLX;
1248  if (!cparse_cplusplus && (strcmp(c, "complex") == 0))
1249    return T_COMPLEX;
1250  if (strcmp(c, "void") == 0)
1251    return T_VOID;
1252  if (strcmp(c, "bool") == 0)
1253    return T_BOOL;
1254  if (strcmp(c, "long long") == 0)
1255    return T_LONGLONG;
1256  if (strcmp(c, "unsigned long long") == 0)
1257    return T_ULONGLONG;
1258  if (strncmp(c, "enum ", 5) == 0)
1259    return T_INT;
1260
1261  if (strcmp(c, "v(...)") == 0)
1262    return T_VARARGS;
1263  /* Hmmm. Unknown type */
1264  if (SwigType_istypedef(t)) {
1265    int r;
1266    SwigType *nt = SwigType_typedef_resolve(t);
1267    r = SwigType_type(nt);
1268    Delete(nt);
1269    return r;
1270  }
1271  return T_USER;
1272}
1273
1274/* -----------------------------------------------------------------------------
1275 * SwigType_alttype()
1276 *
1277 * Returns the alternative value type needed in C++ for class value
1278 * types. When swig is not sure about using a plain $ltype value,
1279 * since the class doesn't have a default constructor, or it can't be
1280 * assigned, you will get back 'SwigValueWrapper<type >'.
1281 *
1282 * This is the default behavior unless:
1283 *
1284 *  1.- swig detects a default_constructor and 'setallocate:default_constructor'
1285 *      attribute.
1286 *
1287 *  2.- swig doesn't mark 'type' as non-assignable.
1288 *
1289 *  3.- the user specify that the value wrapper is not needed by using
1290 *      the %feature("novaluewrapper"), in that case the user need to type
1291 *
1292 *        %feature("novaluewrapper") MyOpaqueClass;
1293 *        class MyOpaqueClass;
1294 *
1295 * Users can also force the use of the value wrapper by using the
1296 * %feature("valuewrapper").
1297 * ----------------------------------------------------------------------------- */
1298
1299SwigType *SwigType_alttype(SwigType *t, int local_tmap) {
1300  Node *n;
1301  SwigType *w = 0;
1302  int use_wrapper = 0;
1303  SwigType *td = 0;
1304
1305  if (!cparse_cplusplus)
1306    return 0;
1307
1308  if (value_wrapper_mode == 0) {
1309    /* old partial use of SwigValueTypes, it can fail for opaque types */
1310    if (local_tmap)
1311      return 0;
1312    if (SwigType_isclass(t)) {
1313      SwigType *ftd = SwigType_typedef_resolve_all(t);
1314      td = SwigType_strip_qualifiers(ftd);
1315      Delete(ftd);
1316      n = Swig_symbol_clookup(td, 0);
1317      if (n) {
1318	if (GetFlag(n, "feature:valuewrapper")) {
1319	  use_wrapper = 1;
1320	} else {
1321	  if (Checkattr(n, "nodeType", "class")
1322	      && (!Getattr(n, "allocate:default_constructor")
1323		  || (Getattr(n, "allocate:noassign")))) {
1324	    use_wrapper = !GetFlag(n, "feature:novaluewrapper") || GetFlag(n, "feature:nodefault");
1325	  }
1326	}
1327      } else {
1328	if (SwigType_issimple(td) && SwigType_istemplate(td)) {
1329	  use_wrapper = !n || !GetFlag(n, "feature:novaluewrapper");
1330	}
1331      }
1332    }
1333  } else {
1334    /* safe use of SwigValueTypes, it can fail with some typemaps */
1335    SwigType *ftd = SwigType_typedef_resolve_all(t);
1336    td = SwigType_strip_qualifiers(ftd);
1337    Delete(ftd);
1338    if (SwigType_type(td) == T_USER) {
1339      use_wrapper = 1;
1340      n = Swig_symbol_clookup(td, 0);
1341      if (n) {
1342	if ((Checkattr(n, "nodeType", "class")
1343	     && !Getattr(n, "allocate:noassign")
1344	     && (Getattr(n, "allocate:default_constructor")))
1345	    || (GetFlag(n, "feature:novaluewrapper"))) {
1346	  use_wrapper = GetFlag(n, "feature:valuewrapper");
1347	}
1348      }
1349    }
1350  }
1351
1352  if (use_wrapper) {
1353    /* Need a space before the type in case it starts "::" (since the <:
1354     * token is a digraph for [ in C++.  Also need a space after the
1355     * type in case it ends with ">" since then we form the token ">>".
1356     */
1357    w = NewStringf("SwigValueWrapper< %s >", td);
1358  }
1359  Delete(td);
1360  return w;
1361}
1362
1363/* ----------------------------------------------------------------------------
1364 *                         * * * WARNING * * *                            ***
1365 *                                                                        ***
1366 * Don't even think about modifying anything below this line unless you   ***
1367 * are completely on top of *EVERY* subtle aspect of the C++ type system  ***
1368 * and you are prepared to suffer endless hours of agony trying to        ***
1369 * debug the SWIG run-time type checker after you break it.               ***
1370 * ------------------------------------------------------------------------- */
1371
1372/* -----------------------------------------------------------------------------
1373 * SwigType_remember()
1374 *
1375 * This function "remembers" a datatype that was used during wrapper code generation
1376 * so that a type-checking table can be generated later on. It is up to the language
1377 * modules to actually call this function--it is not done automatically.
1378 *
1379 * Type tracking is managed through two separate hash tables.  The hash 'r_mangled'
1380 * is mapping between mangled type names (used in the target language) and
1381 * fully-resolved C datatypes used in the source input.   The second hash 'r_resolved'
1382 * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled
1383 * names in the scripting languages.  For example, consider the following set of
1384 * typedef declarations:
1385 *
1386 *      typedef double Real;
1387 *      typedef double Float;
1388 *      typedef double Point[3];
1389 *
1390 * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and
1391 * 'Point' were used in an interface file and "remembered" using this function.
1392 * The hash tables would look like this:
1393 *
1394 * r_mangled {
1395 *   _p_double : [ p.double, a(3).double ]
1396 *   _p_Real   : [ p.double ]
1397 *   _p_Float  : [ p.double ]
1398 *   _Point    : [ a(3).double ]
1399 *
1400 * r_resolved {
1401 *   p.double     : [ _p_double, _p_Real, _p_Float ]
1402 *   a(3).double  : [ _p_double, _Point ]
1403 * }
1404 *
1405 * Together these two hash tables can be used to determine type-equivalency between
1406 * mangled typenames.  To do this, we view the two hash tables as a large graph and
1407 * compute the transitive closure.
1408 * ----------------------------------------------------------------------------- */
1409
1410static Hash *r_mangled = 0;	/* Hash mapping mangled types to fully resolved types */
1411static Hash *r_resolved = 0;	/* Hash mapping resolved types to mangled types       */
1412static Hash *r_ltype = 0;	/* Hash mapping mangled names to their local c type   */
1413static Hash *r_clientdata = 0;	/* Hash mapping resolved types to client data         */
1414static Hash *r_mangleddata = 0;	/* Hash mapping mangled types to client data         */
1415static Hash *r_remembered = 0;	/* Hash of types we remembered already */
1416
1417static void (*r_tracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
1418
1419void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata) {
1420  if (!r_mangleddata) {
1421    r_mangleddata = NewHash();
1422  }
1423  Setattr(r_mangleddata, mangled, clientdata);
1424}
1425
1426
1427void SwigType_remember_clientdata(SwigType *t, const_String_or_char_ptr clientdata) {
1428  String *mt;
1429  SwigType *lt;
1430  Hash *h;
1431  SwigType *fr;
1432  SwigType *qr;
1433  String *tkey;
1434  String *cd;
1435  Hash *lthash;
1436
1437  if (!r_mangled) {
1438    r_mangled = NewHash();
1439    r_resolved = NewHash();
1440    r_ltype = NewHash();
1441    r_clientdata = NewHash();
1442    r_remembered = NewHash();
1443  }
1444
1445  {
1446    String *last;
1447    last = Getattr(r_remembered, t);
1448    if (last && (Cmp(last, clientdata) == 0))
1449      return;
1450  }
1451
1452  tkey = Copy(t);
1453  cd = clientdata ? NewString(clientdata) : NewStringEmpty();
1454  Setattr(r_remembered, tkey, cd);
1455  Delete(tkey);
1456  Delete(cd);
1457
1458  mt = SwigType_manglestr(t);	/* Create mangled string */
1459
1460  if (r_tracefunc) {
1461    (*r_tracefunc) (t, mt, (String *) clientdata);
1462  }
1463
1464  if (SwigType_istypedef(t)) {
1465    lt = Copy(t);
1466  } else {
1467    lt = SwigType_ltype(t);
1468  }
1469
1470  lthash = Getattr(r_ltype, mt);
1471  if (!lthash) {
1472    lthash = NewHash();
1473    Setattr(r_ltype, mt, lthash);
1474  }
1475  Setattr(lthash, lt, "1");
1476  Delete(lt);
1477
1478  fr = SwigType_typedef_resolve_all(t);	/* Create fully resolved type */
1479  qr = SwigType_typedef_qualified(fr);
1480  Delete(fr);
1481
1482  /* Added to deal with possible table bug */
1483  fr = SwigType_strip_qualifiers(qr);
1484  Delete(qr);
1485
1486  /*Printf(stdout,"t = '%s'\n", t);
1487     Printf(stdout,"fr= '%s'\n\n", fr); */
1488
1489  if (t) {
1490    char *ct = Char(t);
1491    if (strchr(ct, '<') && !(strstr(ct, "<("))) {
1492      Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t);
1493      assert(0);
1494    }
1495  }
1496
1497  h = Getattr(r_mangled, mt);
1498  if (!h) {
1499    h = NewHash();
1500    Setattr(r_mangled, mt, h);
1501    Delete(h);
1502  }
1503  Setattr(h, fr, mt);
1504
1505  h = Getattr(r_resolved, fr);
1506  if (!h) {
1507    h = NewHash();
1508    Setattr(r_resolved, fr, h);
1509    Delete(h);
1510  }
1511  Setattr(h, mt, fr);
1512
1513  if (clientdata) {
1514    String *cd = Getattr(r_clientdata, fr);
1515    if (cd) {
1516      if (Strcmp(clientdata, cd) != 0) {
1517	Printf(stderr, "*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr, 0));
1518	Printf(stderr, "*** '%s' != '%s'\n", clientdata, cd);
1519	assert(0);
1520      }
1521    } else {
1522      String *cstr = NewString(clientdata);
1523      Setattr(r_clientdata, fr, cstr);
1524      Delete(cstr);
1525    }
1526  }
1527
1528  /* If the remembered type is a reference, we also remember the pointer version.
1529     This is to prevent odd problems with mixing pointers and references--especially
1530     when different functions are using different typenames (via typedef). */
1531
1532  if (SwigType_isreference(t)) {
1533    SwigType *tt = Copy(t);
1534    SwigType_del_reference(tt);
1535    SwigType_add_pointer(tt);
1536    SwigType_remember_clientdata(tt, clientdata);
1537  }
1538}
1539
1540void SwigType_remember(SwigType *ty) {
1541  SwigType_remember_clientdata(ty, 0);
1542}
1543
1544void (*SwigType_remember_trace(void (*tf) (SwigType *, String *, String *))) (SwigType *, String *, String *) {
1545  void (*o) (SwigType *, String *, String *) = r_tracefunc;
1546  r_tracefunc = tf;
1547  return o;
1548}
1549
1550/* -----------------------------------------------------------------------------
1551 * SwigType_equivalent_mangle()
1552 *
1553 * Return a list of all of the mangled typenames that are equivalent to another
1554 * mangled name.   This works as follows: For each fully qualified C datatype
1555 * in the r_mangled hash entry, we collect all of the mangled names from the
1556 * r_resolved hash and combine them together in a list (removing duplicate entries).
1557 * ----------------------------------------------------------------------------- */
1558
1559List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) {
1560  List *l;
1561  Hash *h;
1562  Hash *ch;
1563  Hash *mh;
1564
1565  if (found) {
1566    h = found;
1567  } else {
1568    h = NewHash();
1569  }
1570  if (checked) {
1571    ch = checked;
1572  } else {
1573    ch = NewHash();
1574  }
1575  if (Getattr(ch, ms))
1576    goto check_exit;		/* Already checked this type */
1577  Setattr(h, ms, "1");
1578  Setattr(ch, ms, "1");
1579  mh = Getattr(r_mangled, ms);
1580  if (mh) {
1581    Iterator ki;
1582    ki = First(mh);
1583    while (ki.key) {
1584      Hash *rh;
1585      if (Getattr(ch, ki.key)) {
1586	ki = Next(ki);
1587	continue;
1588      }
1589      Setattr(ch, ki.key, "1");
1590      rh = Getattr(r_resolved, ki.key);
1591      if (rh) {
1592	Iterator rk;
1593	rk = First(rh);
1594	while (rk.key) {
1595	  Setattr(h, rk.key, "1");
1596	  SwigType_equivalent_mangle(rk.key, ch, h);
1597	  rk = Next(rk);
1598	}
1599      }
1600      ki = Next(ki);
1601    }
1602  }
1603check_exit:
1604  if (!found) {
1605    l = Keys(h);
1606    Delete(h);
1607    Delete(ch);
1608    return l;
1609  } else {
1610    return 0;
1611  }
1612}
1613
1614/* -----------------------------------------------------------------------------
1615 * SwigType_clientdata_collect()
1616 *
1617 * Returns the clientdata field for a mangled type-string.
1618 * ----------------------------------------------------------------------------- */
1619
1620static
1621String *SwigType_clientdata_collect(String *ms) {
1622  Hash *mh;
1623  String *clientdata = 0;
1624
1625  if (r_mangleddata) {
1626    clientdata = Getattr(r_mangleddata, ms);
1627    if (clientdata)
1628      return clientdata;
1629  }
1630
1631  mh = Getattr(r_mangled, ms);
1632  if (mh) {
1633    Iterator ki;
1634    ki = First(mh);
1635    while (ki.key) {
1636      clientdata = Getattr(r_clientdata, ki.key);
1637      if (clientdata)
1638	break;
1639      ki = Next(ki);
1640    }
1641  }
1642  return clientdata;
1643}
1644
1645
1646
1647
1648/* -----------------------------------------------------------------------------
1649 * SwigType_inherit()
1650 *
1651 * Record information about inheritance.  We keep a hash table that keeps
1652 * a mapping between base classes and all of the classes that are derived
1653 * from them.
1654 *
1655 * subclass is a hash that maps base-classes to all of the classes derived from them.
1656 *
1657 * derived - name of derived class
1658 * base - name of base class
1659 * cast - additional casting code when casting from derived to base
1660 * conversioncode - if set, overrides the default code in the function when casting
1661 *                from derived to base
1662 * ----------------------------------------------------------------------------- */
1663
1664static Hash *subclass = 0;
1665static Hash *conversions = 0;
1666
1667void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) {
1668  Hash *h;
1669  String *dd = 0;
1670  String *bb = 0;
1671  if (!subclass)
1672    subclass = NewHash();
1673
1674  /* Printf(stdout,"'%s' --> '%s'  '%s'\n", derived, base, cast); */
1675
1676  if (SwigType_istemplate(derived)) {
1677    String *ty = SwigType_typedef_resolve_all(derived);
1678    dd = SwigType_typedef_qualified(ty);
1679    derived = dd;
1680    Delete(ty);
1681  }
1682  if (SwigType_istemplate(base)) {
1683    String *ty = SwigType_typedef_resolve_all(base);
1684    bb = SwigType_typedef_qualified(ty);
1685    base = bb;
1686    Delete(ty);
1687  }
1688
1689  /* Printf(stdout,"'%s' --> '%s'  '%s'\n", derived, base, cast); */
1690
1691  h = Getattr(subclass, base);
1692  if (!h) {
1693    h = NewHash();
1694    Setattr(subclass, base, h);
1695    Delete(h);
1696  }
1697  if (!Getattr(h, derived)) {
1698    Hash *c = NewHash();
1699    if (cast)
1700      Setattr(c, "cast", cast);
1701    if (conversioncode)
1702      Setattr(c, "convcode", conversioncode);
1703    Setattr(h, derived, c);
1704    Delete(c);
1705  }
1706
1707  Delete(dd);
1708  Delete(bb);
1709}
1710
1711/* -----------------------------------------------------------------------------
1712 * SwigType_issubtype()
1713 *
1714 * Determines if a t1 is a subtype of t2, ie, is t1 derived from t2
1715 * ----------------------------------------------------------------------------- */
1716
1717int SwigType_issubtype(SwigType *t1, SwigType *t2) {
1718  SwigType *ft1, *ft2;
1719  String *b1, *b2;
1720  Hash *h;
1721  int r = 0;
1722
1723  if (!subclass)
1724    return 0;
1725
1726  ft1 = SwigType_typedef_resolve_all(t1);
1727  ft2 = SwigType_typedef_resolve_all(t2);
1728  b1 = SwigType_base(ft1);
1729  b2 = SwigType_base(ft2);
1730
1731  h = Getattr(subclass, b2);
1732  if (h) {
1733    if (Getattr(h, b1)) {
1734      r = 1;
1735    }
1736  }
1737  Delete(ft1);
1738  Delete(ft2);
1739  Delete(b1);
1740  Delete(b2);
1741  /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */
1742  return r;
1743}
1744
1745/* -----------------------------------------------------------------------------
1746 * SwigType_inherit_equiv()
1747 *
1748 * Modify the type table to handle C++ inheritance
1749 * ----------------------------------------------------------------------------- */
1750
1751void SwigType_inherit_equiv(File *out) {
1752  String *ckey;
1753  String *prefix, *base;
1754  String *mprefix, *mkey;
1755  Hash *sub;
1756  Hash *rh;
1757  List *rlist;
1758  Iterator rk, bk, ck;
1759
1760  if (!conversions)
1761    conversions = NewHash();
1762  if (!subclass)
1763    subclass = NewHash();
1764
1765  rk = First(r_resolved);
1766  while (rk.key) {
1767    /* rkey is a fully qualified type.  We strip all of the type constructors off of it just to get the base */
1768    base = SwigType_base(rk.key);
1769    /* Check to see whether the base is recorded in the subclass table */
1770    sub = Getattr(subclass, base);
1771    Delete(base);
1772    if (!sub) {
1773      rk = Next(rk);
1774      continue;
1775    }
1776
1777    /* This type has subclasses.  We now need to walk through these subtypes and generate pointer converion functions */
1778
1779    rh = Getattr(r_resolved, rk.key);
1780    rlist = NewList();
1781    for (ck = First(rh); ck.key; ck = Next(ck)) {
1782      Append(rlist, ck.key);
1783    }
1784    /*    Printf(stdout,"rk.key = '%s'\n", rk.key);
1785       Printf(stdout,"rh = %x '%s'\n", rh,rh); */
1786
1787    bk = First(sub);
1788    while (bk.key) {
1789      prefix = SwigType_prefix(rk.key);
1790      Append(prefix, bk.key);
1791      /*      Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
1792      mprefix = SwigType_manglestr(prefix);
1793      Setattr(rh, mprefix, prefix);
1794      mkey = SwigType_manglestr(rk.key);
1795      ckey = NewStringf("%s+%s", mprefix, mkey);
1796      if (!Getattr(conversions, ckey)) {
1797	String *convname = NewStringf("%sTo%s", mprefix, mkey);
1798	String *lkey = SwigType_lstr(rk.key, 0);
1799	String *lprefix = SwigType_lstr(prefix, 0);
1800        Hash *subhash = Getattr(sub, bk.key);
1801        String *convcode = Getattr(subhash, "convcode");
1802        if (convcode) {
1803          char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */
1804          String *fn = Copy(convcode);
1805          Replaceall(fn, "$from", "x");
1806          Printf(out, "static void *%s(void *x, int *%s) {", convname, newmemoryused ? "newmemory" : "SWIGUNUSEDPARM(newmemory)");
1807          Printf(out, "%s", fn);
1808        } else {
1809          String *cast = Getattr(subhash, "cast");
1810          Printf(out, "static void *%s(void *x, int *SWIGUNUSEDPARM(newmemory)) {", convname);
1811          Printf(out, "\n    return (void *)((%s) ", lkey);
1812          if (cast)
1813            Printf(out, "%s", cast);
1814          Printf(out, " ((%s) x));\n", lprefix);
1815        }
1816	Printf(out, "}\n");
1817	Setattr(conversions, ckey, convname);
1818	Delete(ckey);
1819	Delete(lkey);
1820	Delete(lprefix);
1821
1822	/* This inserts conversions for typedefs */
1823	{
1824	  Hash *r = Getattr(r_resolved, prefix);
1825	  if (r) {
1826	    Iterator rrk;
1827	    rrk = First(r);
1828	    while (rrk.key) {
1829	      Iterator rlk;
1830	      String *rkeymangle;
1831
1832	      /* Make sure this name equivalence is not due to inheritance */
1833	      if (Cmp(prefix, Getattr(r, rrk.key)) == 0) {
1834		rkeymangle = Copy(mkey);
1835		ckey = NewStringf("%s+%s", rrk.key, rkeymangle);
1836		if (!Getattr(conversions, ckey)) {
1837		  Setattr(conversions, ckey, convname);
1838		}
1839		Delete(ckey);
1840		for (rlk = First(rlist); rlk.item; rlk = Next(rlk)) {
1841		  ckey = NewStringf("%s+%s", rrk.key, rlk.item);
1842		  Setattr(conversions, ckey, convname);
1843		  Delete(ckey);
1844		}
1845		Delete(rkeymangle);
1846		/* This is needed to pick up other alternative names for the same type.
1847		   Needed to make templates work */
1848		Setattr(rh, rrk.key, rrk.item);
1849	      }
1850	      rrk = Next(rrk);
1851	    }
1852	  }
1853	}
1854	Delete(convname);
1855      }
1856      Delete(prefix);
1857      Delete(mprefix);
1858      Delete(mkey);
1859      bk = Next(bk);
1860    }
1861    rk = Next(rk);
1862    Delete(rlist);
1863  }
1864}
1865
1866/* Helper function to sort the mangled list */
1867static int SwigType_compare_mangled(const DOH *a, const DOH *b) {
1868  return strcmp((char *) Data(a), (char *) Data(b));
1869}
1870
1871/* -----------------------------------------------------------------------------
1872 * SwigType_get_sorted_mangled_list()
1873 *
1874 * Returns the sorted list of mangled type names that should be exported into the
1875 * wrapper file.
1876 * ----------------------------------------------------------------------------- */
1877List *SwigType_get_sorted_mangled_list() {
1878  List *l = Keys(r_mangled);
1879  SortList(l, SwigType_compare_mangled);
1880  return l;
1881}
1882
1883
1884/* -----------------------------------------------------------------------------
1885 * SwigType_type_table()
1886 *
1887 * Generate the type-table for the type-checker.
1888 * ----------------------------------------------------------------------------- */
1889
1890void SwigType_emit_type_table(File *f_forward, File *f_table) {
1891  Iterator ki;
1892  String *types, *table, *cast, *cast_init, *cast_temp;
1893  Hash *imported_types;
1894  List *mangled_list;
1895  List *table_list = NewList();
1896  int i = 0;
1897
1898  if (!r_mangled) {
1899    r_mangled = NewHash();
1900    r_resolved = NewHash();
1901  }
1902
1903  Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n");
1904
1905  SwigType_inherit_equiv(f_table);
1906
1907   /*#define DEBUG 1*/
1908#ifdef DEBUG
1909  Printf(stdout, "---r_mangled---\n");
1910  Printf(stdout, "%s\n", r_mangled);
1911
1912  Printf(stdout, "---r_resolved---\n");
1913  Printf(stdout, "%s\n", r_resolved);
1914
1915  Printf(stdout, "---r_ltype---\n");
1916  Printf(stdout, "%s\n", r_ltype);
1917
1918  Printf(stdout, "---subclass---\n");
1919  Printf(stdout, "%s\n", subclass);
1920
1921  Printf(stdout, "---conversions---\n");
1922  Printf(stdout, "%s\n", conversions);
1923
1924  Printf(stdout, "---r_clientdata---\n");
1925  Printf(stdout, "%s\n", r_clientdata);
1926
1927#endif
1928  table = NewStringEmpty();
1929  types = NewStringEmpty();
1930  cast = NewStringEmpty();
1931  cast_init = NewStringEmpty();
1932  imported_types = NewHash();
1933
1934  Printf(table, "static swig_type_info *swig_type_initial[] = {\n");
1935  Printf(cast_init, "static swig_cast_info *swig_cast_initial[] = {\n");
1936
1937  Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
1938
1939  mangled_list = SwigType_get_sorted_mangled_list();
1940  for (ki = First(mangled_list); ki.item; ki = Next(ki)) {
1941    List *el;
1942    Iterator ei;
1943    SwigType *lt;
1944    SwigType *rt = 0;
1945    String *nt;
1946    String *ln;
1947    String *rn;
1948    const String *cd;
1949    Hash *lthash;
1950    Iterator ltiter;
1951    Hash *nthash;
1952
1953    cast_temp = NewStringEmpty();
1954
1955    Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL);
1956    Append(table_list, ki.item);
1957    Printf(cast_temp, "static swig_cast_info _swigc_%s[] = {", ki.item);
1958    i++;
1959
1960    cd = SwigType_clientdata_collect(ki.item);
1961    if (!cd)
1962      cd = "0";
1963
1964    lthash = Getattr(r_ltype, ki.item);
1965    nt = 0;
1966    nthash = NewHash();
1967    ltiter = First(lthash);
1968    while (ltiter.key) {
1969      lt = ltiter.key;
1970      rt = SwigType_typedef_resolve_all(lt);
1971      /* we save the original type and the fully resolved version */
1972      ln = SwigType_lstr(lt, 0);
1973      rn = SwigType_lstr(rt, 0);
1974      if (Equal(ln, rn)) {
1975        Setattr(nthash, ln, "1");
1976      } else {
1977	Setattr(nthash, rn, "1");
1978	Setattr(nthash, ln, "1");
1979      }
1980      if (SwigType_istemplate(rt)) {
1981        String *dt = Swig_symbol_template_deftype(rt, 0);
1982        String *dn = SwigType_lstr(dt, 0);
1983        if (!Equal(dn, rn) && !Equal(dn, ln)) {
1984          Setattr(nthash, dn, "1");
1985        }
1986        Delete(dt);
1987        Delete(dn);
1988      }
1989
1990      ltiter = Next(ltiter);
1991    }
1992
1993    /* now build nt */
1994    ltiter = First(nthash);
1995    nt = 0;
1996    while (ltiter.key) {
1997      if (nt) {
1998	 Printf(nt, "|%s", ltiter.key);
1999      } else {
2000	 nt = NewString(ltiter.key);
2001      }
2002      ltiter = Next(ltiter);
2003    }
2004    Delete(nthash);
2005
2006    Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd);
2007
2008    el = SwigType_equivalent_mangle(ki.item, 0, 0);
2009    for (ei = First(el); ei.item; ei = Next(ei)) {
2010      String *ckey;
2011      String *conv;
2012      ckey = NewStringf("%s+%s", ei.item, ki.item);
2013      conv = Getattr(conversions, ckey);
2014      if (conv) {
2015	Printf(cast_temp, "  {&_swigt_%s, %s, 0, 0},", ei.item, conv);
2016      } else {
2017	Printf(cast_temp, "  {&_swigt_%s, 0, 0, 0},", ei.item);
2018      }
2019      Delete(ckey);
2020
2021      if (!Getattr(r_mangled, ei.item) && !Getattr(imported_types, ei.item)) {
2022	Printf(types, "static swig_type_info _swigt_%s = {\"%s\", 0, 0, 0, 0, 0};\n", ei.item, ei.item);
2023	Append(table_list, ei.item);
2024
2025	Printf(cast, "static swig_cast_info _swigc_%s[] = {{&_swigt_%s, 0, 0, 0},{0, 0, 0, 0}};\n", ei.item, ei.item);
2026	i++;
2027
2028	Setattr(imported_types, ei.item, "1");
2029      }
2030    }
2031    Delete(el);
2032    Printf(cast, "%s{0, 0, 0, 0}};\n", cast_temp);
2033    Delete(cast_temp);
2034    Delete(nt);
2035    Delete(rt);
2036  }
2037  /* print the tables in the proper order */
2038  SortList(table_list, SwigType_compare_mangled);
2039  i = 0;
2040  for (ki = First(table_list); ki.item; ki = Next(ki)) {
2041    Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++);
2042    Printf(table, "  &_swigt_%s,\n", ki.item);
2043    Printf(cast_init, "  _swigc_%s,\n", ki.item);
2044  }
2045  if (i == 0) {
2046    /* empty arrays are not allowed by ISO C */
2047    Printf(table, "  NULL\n");
2048    Printf(cast_init, "  NULL\n");
2049  }
2050
2051  Delete(table_list);
2052
2053  Delete(mangled_list);
2054
2055  Printf(table, "};\n");
2056  Printf(cast_init, "};\n");
2057  Printf(f_table, "%s\n", types);
2058  Printf(f_table, "%s\n", table);
2059  Printf(f_table, "%s\n", cast);
2060  Printf(f_table, "%s\n", cast_init);
2061  Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n");
2062
2063  Printf(f_forward, "static swig_type_info *swig_types[%d];\n", i + 1);
2064  Printf(f_forward, "static swig_module_info swig_module = {swig_types, %d, 0, 0, 0, 0};\n", i);
2065  Printf(f_forward, "#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)\n");
2066  Printf(f_forward, "#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)\n");
2067  Printf(f_forward, "\n/* -------- TYPES TABLE (END) -------- */\n\n");
2068
2069  Delete(types);
2070  Delete(table);
2071  Delete(cast);
2072  Delete(cast_init);
2073  Delete(imported_types);
2074}
2075