import source from 1.3.40
[external/swig.git] / Source / Swig / typesys.c
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
13 char 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
99 static Typetab *current_scope = 0;      /* Current type scope                           */
100 static Hash *current_typetab = 0;       /* Current type table                           */
101 static Hash *current_symtab = 0;        /* Current symbol table                         */
102 static Typetab *global_scope = 0;       /* The global scope                             */
103 static Hash *scopes = 0;        /* Hash table containing fully qualified scopes */
104
105 /* Performance optimization */
106 #define SWIG_TYPEDEF_RESOLVE_CACHE
107 static Hash *typedef_resolve_cache = 0;
108 static Hash *typedef_all_cache = 0;
109 static Hash *typedef_qualified_cache = 0;
110
111 static 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 */
125 static int value_wrapper_mode = 0;
126 int Swig_value_wrapper_mode(int mode) {
127   value_wrapper_mode = mode;
128   return mode;
129 }
130
131
132 static 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
140 void 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
166 int 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
196 int 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
215 String *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
235 void 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
268 void 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
294 void 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
312 void 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
342 Typetab *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
360 Typetab *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
377 void 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
388 void 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
413 static 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
484 static Typetab *resolved_scope = 0;
485
486 /* Internal function */
487
488 static 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
532 static 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 */
542 SwigType *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
781 return_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
805 SwigType *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
846 SwigType *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
1055 int 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
1075 int 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
1154 int 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
1190 int 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
1299 SwigType *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
1410 static Hash *r_mangled = 0;     /* Hash mapping mangled types to fully resolved types */
1411 static Hash *r_resolved = 0;    /* Hash mapping resolved types to mangled types       */
1412 static Hash *r_ltype = 0;       /* Hash mapping mangled names to their local c type   */
1413 static Hash *r_clientdata = 0;  /* Hash mapping resolved types to client data         */
1414 static Hash *r_mangleddata = 0; /* Hash mapping mangled types to client data         */
1415 static Hash *r_remembered = 0;  /* Hash of types we remembered already */
1416
1417 static void (*r_tracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
1418
1419 void 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
1427 void 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
1540 void SwigType_remember(SwigType *ty) {
1541   SwigType_remember_clientdata(ty, 0);
1542 }
1543
1544 void (*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
1559 List *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   }
1603 check_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
1620 static
1621 String *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
1664 static Hash *subclass = 0;
1665 static Hash *conversions = 0;
1666
1667 void 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
1717 int 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
1751 void 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 */
1867 static 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  * ----------------------------------------------------------------------------- */
1877 List *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
1890 void 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 }