1 /* -----------------------------------------------------------------------------
2  * This file is part of SWIG, which is licensed as a whole under version 3
3  * (or any later version) of the GNU General Public License. Some additional
4  * terms also apply to certain portions of SWIG. The full details of the SWIG
5  * license and copyrights can be found in the LICENSE and COPYRIGHT files
6  * included with the SWIG source code as distributed by the SWIG developers
7  * and at http://www.swig.org/legal.html.
8  *
9  * symbol.c
10  *
11  * This file implements the SWIG symbol table.  See details below.
12  * ----------------------------------------------------------------------------- */
13 
14 #include "swig.h"
15 #include "swigwarn.h"
16 #include <ctype.h>
17 
18 /* #define SWIG_DEBUG*/
19 /* -----------------------------------------------------------------------------
20  * Synopsis
21  *
22  * This module provides symbol table management for all of SWIG.  In previous
23  * releases, the management of symbols was rather haphazard.  This module tries
24  * to correct that.
25  *
26  * All symbols are associated with simple identifiers.  For example, here are some
27  * declarations that generate symbol table entries:
28  *
29  *  decl                                    symbol
30  *  --------------                          ------------
31  *  void foo(int);                          foo
32  *  int  x;                                 x
33  *  typedef int *blah;                      blah
34  *
35  * Associated with each symbol is a Hash table that can contain any set of
36  * attributes that make sense for that object.  For example:
37  *
38  *  typedef int *blah;             ---->    "name" : 'blah'
39  *                                          "type" : 'int'
40  *                                          "decl" : 'p.'
41  *                                       "storage" : 'typedef'
42  *
43  * In some cases, the symbol table needs to manage overloaded entries.  For instance,
44  * overloaded functions.  In this case, a linked list is built.  The "sym:nextSibling"
45  * attribute is reserved to hold a link to the next entry.  For example:
46  *
47  * int foo(int);            --> "name" : "foo"         "name" : "foo"
48  * int foo(int,double);         "type" : "int"         "type" : "int"
49  *                              "decl" : "f(int)."     "decl" : "f(int,double)."
50  *                               ...                    ...
51  *                   "sym:nextSibling" :  --------> "sym:nextSibling": --------> ...
52  *
53  * When more than one symbol has the same name, the symbol declarator is
54  * used to detect duplicates.  For example, in the above case, foo(int) and
55  * foo(int,double) are different because their "decl" attribute is different.
56  * However, if a third declaration "foo(int)" was made, it would generate a
57  * conflict (due to having a declarator that matches a previous entry).
58  *
59  * Structures and classes:
60  *
61  * C/C++ symbol tables are normally managed in a few different spaces.  The
62  * most visible namespace is reserved for functions, variables, typedef, enum values
63  * and such.  In C, a separate tag-space is reserved for 'struct name', 'class name',
64  * and 'union name' declarations.   In SWIG, a single namespace is used for everything
65  * this means that certain incompatibilities will arise with some C programs. For instance:
66  *
67  *        struct Foo {
68  *             ...
69  *        }
70  *
71  *        int Foo();       // Error. Name clash.  Works in C though
72  *
73  * Due to the unified namespace for structures, special handling is performed for
74  * the following:
75  *
76  *        typedef struct Foo {
77  *
78  *        } Foo;
79  *
80  * In this case, the symbol table contains an entry for the structure itself.  The
81  * typedef is left out of the symbol table.
82  *
83  * Target language vs C:
84  *
85  * The symbol tables are normally managed *in the namespace of the target language*.
86  * This means that name-collisions can be resolved using %rename and related
87  * directives.   A quirk of this is that sometimes the symbol tables need to
88  * be used for C type resolution as well.  To handle this, each symbol table
89  * also has a C-symbol table lurking behind the scenes.  This is used to locate
90  * symbols in the C namespace.  However, this symbol table is not used for error
91  * reporting nor is it used for anything else during code generation.
92  *
93  * Symbol table structure:
94  *
95  * Symbol tables themselves are a special kind of node that is organized just like
96  * a normal parse tree node.  Symbol tables are organized in a tree that can be
97  * traversed using the SWIG-DOM API. The following attributes names are reserved.
98  *
99  *     name           -- Name of the scope defined by the symbol table (if any)
100  *                       This name is the C-scope name and is not affected by
101  *                       %renaming operations
102  *     symtab         -- Hash table mapping identifiers to nodes.
103  *     csymtab        -- Hash table mapping C identifiers to nodes.
104  *
105  * Reserved attributes on symbol objects:
106  *
107  * When a symbol is placed in the symbol table, the following attributes
108  * are set:
109  *
110  *     sym:name             -- Symbol name
111  *     sym:nextSibling      -- Next symbol (if overloaded)
112  *     sym:previousSibling  -- Previous symbol (if overloaded)
113  *     sym:symtab           -- Symbol table object holding the symbol
114  *     sym:overloaded       -- Set to the first symbol if overloaded
115  *
116  * These names are modeled after XML namespaces.  In particular, every attribute
117  * pertaining to symbol table management is prefaced by the "sym:" prefix.
118  *
119  * An example dump of the parse tree showing symbol table entries for the
120  * following code should clarify this:
121  *
122  *   namespace OuterNamespace {
123  *       namespace InnerNamespace {
124  *           class Class {
125  *           };
126  *           struct Struct {
127  *               int Var;
128  *           };
129  *       }
130  *    }
131  *
132  *   +++ namespace ----------------------------------------
133  *   | sym:name     - "OuterNamespace"
134  *   | symtab       - 0xa064bf0
135  *   | sym:symtab   - 0xa041690
136  *   | sym:overname - "__SWIG_0"
137  *
138  *         +++ namespace ----------------------------------------
139  *         | sym:name     - "InnerNamespace"
140  *         | symtab       - 0xa064cc0
141  *         | sym:symtab   - 0xa064bf0
142  *         | sym:overname - "__SWIG_0"
143  *
144  *               +++ class ----------------------------------------
145  *               | sym:name     - "Class"
146  *               | symtab       - 0xa064d80
147  *               | sym:symtab   - 0xa064cc0
148  *               | sym:overname - "__SWIG_0"
149  *               |
150  *               +++ class ----------------------------------------
151  *               | sym:name     - "Struct"
152  *               | symtab       - 0xa064f00
153  *               | sym:symtab   - 0xa064cc0
154  *               | sym:overname - "__SWIG_0"
155  *
156  *                     +++ cdecl ----------------------------------------
157  *                     | sym:name     - "Var"
158  *                     | sym:symtab   - 0xa064f00
159  *                     | sym:overname - "__SWIG_0"
160  *                     |
161  *
162  *
163  * Each class and namespace has its own scope and thus a new symbol table (sym)
164  * is created. The sym attribute is only set for the first entry in the symbol
165  * table. The sym:symtab entry points to the symbol table in which the symbol
166  * exists, so for example, Struct is in the scope OuterNamespace::InnerNamespace
167  * so sym:symtab points to this symbol table (0xa064cc0).
168  *
169  * ----------------------------------------------------------------------------- */
170 
171 static Hash *current = 0;	/* The current symbol table hash */
172 static Hash *ccurrent = 0;	/* The current c symbol table hash */
173 static Hash *current_symtab = 0;	/* Current symbol table node */
174 static Hash *symtabs = 0;	/* Hash of all symbol tables by fully-qualified name */
175 static Hash *global_scope = 0;	/* Global scope */
176 
177 static int use_inherit = 1;
178 
179 /* common attribute keys, to avoid calling find_key all the times */
180 
181 
182 /* -----------------------------------------------------------------------------
183  * Swig_symbol_print_tables()
184  *
185  * Debug display of symbol tables
186  * ----------------------------------------------------------------------------- */
187 
Swig_symbol_print_tables(Symtab * symtab)188 void Swig_symbol_print_tables(Symtab *symtab) {
189   if (!symtab)
190     symtab = current_symtab;
191 
192   Printf(stdout, "SYMBOL TABLES start  =======================================\n");
193   Swig_print_tree(symtab);
194   Printf(stdout, "SYMBOL TABLES finish =======================================\n");
195 }
196 
197 /* -----------------------------------------------------------------------------
198  * Swig_symbol_print_tables_summary()
199  *
200  * Debug summary display of all symbol tables by fully-qualified name
201  * ----------------------------------------------------------------------------- */
202 
Swig_symbol_print_tables_summary(void)203 void Swig_symbol_print_tables_summary(void) {
204   Printf(stdout, "SYMBOL TABLES SUMMARY start  =======================================\n");
205   Swig_print_node(symtabs);
206   Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n");
207 }
208 
209 /* -----------------------------------------------------------------------------
210  * symbol_print_symbols()
211  * ----------------------------------------------------------------------------- */
212 
symbol_print_symbols(const char * symboltabletype,const char * nextSibling)213 static void symbol_print_symbols(const char *symboltabletype, const char *nextSibling) {
214   Node *table = symtabs;
215   Iterator ki = First(table);
216   int show_pointers = 0;
217   while (ki.key) {
218     String *k = ki.key;
219     Printf(stdout, "===================================================\n");
220     Printf(stdout, "%s -\n", k);
221     {
222       Symtab *symtab = Getattr(Getattr(table, k), symboltabletype);
223       Iterator it = First(symtab);
224       while (it.key) {
225 	String *symname = it.key;
226 	Printf(stdout, "  %s (%s)", symname, nodeType(it.item));
227         if (show_pointers)
228 	  Printf(stdout, " %p", it.item);
229 	Printf(stdout, "\n");
230 	{
231 	  Node *sibling = Getattr(it.item, nextSibling);
232 	  while (sibling) {
233 	    Printf(stdout, "  %s (%s)", symname, nodeType(sibling));
234 	    if (show_pointers)
235 	      Printf(stdout, " %p", sibling);
236 	    Printf(stdout, "\n");
237 	    sibling = Getattr(sibling, nextSibling);
238 	  }
239 	}
240 	it = Next(it);
241       }
242     }
243     ki = Next(ki);
244   }
245 }
246 
247 /* -----------------------------------------------------------------------------
248  * Swig_symbol_print_symbols()
249  *
250  * Debug display of all the target language symbols
251  * ----------------------------------------------------------------------------- */
252 
Swig_symbol_print_symbols(void)253 void Swig_symbol_print_symbols(void) {
254   Printf(stdout, "SYMBOLS start  =======================================\n");
255   symbol_print_symbols("symtab", "sym:nextSibling");
256   Printf(stdout, "SYMBOLS finish =======================================\n");
257 }
258 
259 /* -----------------------------------------------------------------------------
260  * Swig_symbol_print_csymbols()
261  *
262  * Debug display of all the C symbols
263  * ----------------------------------------------------------------------------- */
264 
Swig_symbol_print_csymbols(void)265 void Swig_symbol_print_csymbols(void) {
266   Printf(stdout, "CSYMBOLS start  =======================================\n");
267   symbol_print_symbols("csymtab", "csym:nextSibling");
268   Printf(stdout, "CSYMBOLS finish =======================================\n");
269 }
270 
271 /* -----------------------------------------------------------------------------
272  * Swig_symbol_init()
273  *
274  * Create a new symbol table object
275  * ----------------------------------------------------------------------------- */
276 
Swig_symbol_init(void)277 void Swig_symbol_init(void) {
278 
279   current = NewHash();
280   current_symtab = NewHash();
281   ccurrent = NewHash();
282   set_nodeType(current_symtab, "symboltable");
283   Setattr(current_symtab, "symtab", current);
284   Delete(current);
285   Setattr(current_symtab, "csymtab", ccurrent);
286   Delete(ccurrent);
287 
288   /* Set the global scope */
289   symtabs = NewHash();
290   Setattr(symtabs, "", current_symtab);
291   Delete(current_symtab);
292   global_scope = current_symtab;
293 }
294 
295 /* -----------------------------------------------------------------------------
296  * Swig_symbol_setscopename()
297  *
298  * Set the C scopename of the current symbol table.
299  * ----------------------------------------------------------------------------- */
300 
Swig_symbol_setscopename(const_String_or_char_ptr name)301 void Swig_symbol_setscopename(const_String_or_char_ptr name) {
302   String *qname;
303   /* assert(!Getattr(current_symtab,"name")); */
304   Setattr(current_symtab, "name", name);
305 
306   /* Set nested scope in parent */
307 
308   qname = Swig_symbol_qualifiedscopename(current_symtab);
309 
310   /* Save a reference to this scope */
311   Setattr(symtabs, qname, current_symtab);
312   Delete(qname);
313 }
314 
315 /* -----------------------------------------------------------------------------
316  * Swig_symbol_getscopename()
317  *
318  * Get the C scopename of the current symbol table
319  * ----------------------------------------------------------------------------- */
320 
Swig_symbol_getscopename(void)321 String *Swig_symbol_getscopename(void) {
322   return Getattr(current_symtab, "name");
323 }
324 
325 /* -----------------------------------------------------------------------------
326  * Swig_symbol_getscope()
327  *
328  * Given a fully qualified C scopename, this function returns a symbol table
329  * ----------------------------------------------------------------------------- */
330 
Swig_symbol_getscope(const_String_or_char_ptr name)331 Symtab *Swig_symbol_getscope(const_String_or_char_ptr name) {
332   if (!symtabs)
333     return 0;
334   if (Equal("::", (const_String_or_char_ptr ) name))
335     name = "";
336   return Getattr(symtabs, name);
337 }
338 
339 /* -----------------------------------------------------------------------------
340  * Swig_symbol_qualifiedscopename()
341  *
342  * Get the fully qualified C scopename of a symbol table.  Note, this only pertains
343  * to the C/C++ scope name.  It is not affected by renaming.
344  * ----------------------------------------------------------------------------- */
345 
Swig_symbol_qualifiedscopename(Symtab * symtab)346 String *Swig_symbol_qualifiedscopename(Symtab *symtab) {
347   String *result = 0;
348   Hash *parent;
349   String *name;
350   if (!symtab)
351     symtab = current_symtab;
352   parent = Getattr(symtab, "parentNode");
353   if (parent) {
354     result = Swig_symbol_qualifiedscopename(parent);
355   }
356   name = Getattr(symtab, "name");
357   if (name) {
358     if (!result) {
359       result = NewStringEmpty();
360     }
361     if (Len(result)) {
362       Printv(result, "::", name, NIL);
363     } else {
364       Append(result, name);
365     }
366   }
367   return result;
368 }
369 
370 /* -----------------------------------------------------------------------------
371  * Swig_symbol_qualified_language_scopename()
372  *
373  * Get the fully qualified C scopename of a symbol table but using a language
374  * specific separator for the scopenames. Basically the same as
375  * Swig_symbol_qualifiedscopename() but using the different separator.
376  * ----------------------------------------------------------------------------- */
377 
Swig_symbol_qualified_language_scopename(Symtab * n)378 String *Swig_symbol_qualified_language_scopename(Symtab *n) {
379   /* TODO: fix for %rename to work */
380   String *result = Swig_symbol_qualifiedscopename(n);
381   Replaceall(result, "::", NSPACE_SEPARATOR);
382   return result;
383 }
384 
385 /* -----------------------------------------------------------------------------
386  * Swig_symbol_newscope()
387  *
388  * Create a new scope.  Returns the newly created scope.
389  * ----------------------------------------------------------------------------- */
390 
Swig_symbol_newscope(void)391 Symtab *Swig_symbol_newscope(void) {
392   Hash *n;
393   Hash *hsyms, *h;
394 
395   hsyms = NewHash();
396   h = NewHash();
397 
398   set_nodeType(h, "symboltable");
399   Setattr(h, "symtab", hsyms);
400   Delete(hsyms);
401   set_parentNode(h, current_symtab);
402 
403   n = lastChild(current_symtab);
404   if (!n) {
405     set_firstChild(current_symtab, h);
406   } else {
407     set_nextSibling(n, h);
408     Delete(h);
409   }
410   set_lastChild(current_symtab, h);
411   current = hsyms;
412   ccurrent = NewHash();
413   Setattr(h, "csymtab", ccurrent);
414   Delete(ccurrent);
415   current_symtab = h;
416   return h;
417 }
418 
419 /* -----------------------------------------------------------------------------
420  * Swig_symbol_setscope()
421  *
422  * Set the current scope.  Returns the previous current scope.
423  * ----------------------------------------------------------------------------- */
424 
Swig_symbol_setscope(Symtab * sym)425 Symtab *Swig_symbol_setscope(Symtab *sym) {
426   Symtab *ret = current_symtab;
427   current_symtab = sym;
428   current = Getattr(sym, "symtab");
429   assert(current);
430   ccurrent = Getattr(sym, "csymtab");
431   assert(ccurrent);
432   return ret;
433 }
434 
435 /* -----------------------------------------------------------------------------
436  * Swig_symbol_popscope()
437  *
438  * Pop out of the current scope.  Returns the popped scope and sets the
439  * scope to the parent scope.
440  * ----------------------------------------------------------------------------- */
441 
Swig_symbol_popscope(void)442 Symtab *Swig_symbol_popscope(void) {
443   Hash *h = current_symtab;
444   current_symtab = Getattr(current_symtab, "parentNode");
445   assert(current_symtab);
446   current = Getattr(current_symtab, "symtab");
447   assert(current);
448   ccurrent = Getattr(current_symtab, "csymtab");
449   assert(ccurrent);
450   return h;
451 }
452 
453 /* -----------------------------------------------------------------------------
454  * Swig_symbol_global_scope()
455  *
456  * Return the symbol table for the global scope.
457  * ----------------------------------------------------------------------------- */
458 
Swig_symbol_global_scope(void)459 Symtab *Swig_symbol_global_scope(void) {
460   return global_scope;
461 }
462 
463 /* -----------------------------------------------------------------------------
464  * Swig_symbol_current()
465  *
466  * Return the current symbol table.
467  * ----------------------------------------------------------------------------- */
468 
Swig_symbol_current(void)469 Symtab *Swig_symbol_current(void) {
470   return current_symtab;
471 }
472 
473 /* -----------------------------------------------------------------------------
474  * Swig_symbol_alias()
475  *
476  * Makes an alias for a symbol in the global symbol table.
477  * Primarily for namespace aliases such as 'namespace X = Y;'.
478  * ----------------------------------------------------------------------------- */
479 
Swig_symbol_alias(const_String_or_char_ptr aliasname,Symtab * s)480 void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) {
481   String *qname = Swig_symbol_qualifiedscopename(current_symtab);
482   if (qname) {
483     Printf(qname, "::%s", aliasname);
484   } else {
485     qname = NewString(aliasname);
486   }
487   if (!Getattr(symtabs, qname)) {
488     Setattr(symtabs, qname, s);
489   }
490   Delete(qname);
491 }
492 
493 /* -----------------------------------------------------------------------------
494  * Swig_symbol_inherit()
495  *
496  * Inherit symbols from another scope. Primarily for C++ inheritance and
497  * for using directives, such as 'using namespace X;'
498  * but not for using declarations, such as 'using A;'.
499  * ----------------------------------------------------------------------------- */
500 
Swig_symbol_inherit(Symtab * s)501 void Swig_symbol_inherit(Symtab *s) {
502   int i, ilen;
503   List *inherit = Getattr(current_symtab, "inherit");
504   if (!inherit) {
505     inherit = NewList();
506     Setattr(current_symtab, "inherit", inherit);
507     Delete(inherit);
508   }
509 
510   if (s == current_symtab) {
511     Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(s), Getline(s), "Recursive scope inheritance of '%s'.\n", Getattr(s, "name"));
512     return;
513   }
514   assert(s != current_symtab);
515   ilen = Len(inherit);
516   for (i = 0; i < ilen; i++) {
517     Node *n = Getitem(inherit, i);
518     if (n == s)
519       return;			/* Already inherited */
520   }
521   Append(inherit, s);
522 }
523 
524 /* -----------------------------------------------------------------------------
525  * Swig_symbol_cadd()
526  *
527  * Adds a node to the C symbol table only.
528  * ----------------------------------------------------------------------------- */
529 
Swig_symbol_cadd(const_String_or_char_ptr name,Node * n)530 void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
531   Node *append = 0;
532   Node *cn;
533   /* There are a few options for weak symbols.  A "weak" symbol
534      is any symbol that can be replaced by another symbol in the C symbol
535      table.  An example would be a forward class declaration.  A forward
536      class sits in the symbol table until a real class declaration comes along.
537 
538      Certain symbols are marked as "sym:typename".  These are important
539      symbols related to the C++ type-system and take precedence in the C
540      symbol table.  An example might be code like this:
541 
542      template<class T> T foo(T x);
543      int foo(int);
544 
545      In this case, the template is marked with "sym:typename" so that it
546      stays in the C symbol table (so that it can be expanded using %template).
547    */
548 
549   if (!name)
550     return;
551 
552   if (SwigType_istemplate(name)) {
553     String *cname = NewString(name);
554     String *dname = Swig_symbol_template_deftype(cname, 0);
555     if (!Equal(dname, name)) {
556       Swig_symbol_cadd(dname, n);
557     }
558     Delete(dname);
559     Delete(cname);
560   }
561 #ifdef SWIG_DEBUG
562   Printf(stderr, "symbol_cadd %s %p\n", name, n);
563 #endif
564   cn = Getattr(ccurrent, name);
565 
566   if (cn && (Getattr(cn, "sym:typename"))) {
567     /* The node in the C symbol table is a typename.  Do nothing */
568     /* We might append the symbol at the end */
569     append = n;
570   } else if (cn && (Getattr(cn, "sym:weak"))) {
571     /* The node in the symbol table is weak. Replace it */
572     if (checkAttribute(cn, "nodeType", "template")
573 	&& checkAttribute(cn, "templatetype", "classforward")) {
574       /* The node is a template classforward declaration, and the
575          default template parameters here take precedence. */
576       ParmList *pc = Getattr(cn, "templateparms");
577       ParmList *pn = Getattr(n, "templateparms");
578 #ifdef SWIG_DEBUG
579       Printf(stderr, "found template classforward %s\n", Getattr(cn, "name"));
580 #endif
581       while (pc && pn) {
582 	String *value = Getattr(pc, "value");
583 	if (value) {
584 #ifdef SWIG_DEBUG
585 	  Printf(stderr, "add default template value %s %s\n", Getattr(pc, "name"), value);
586 #endif
587 	  Setattr(pn, "value", value);
588 	}
589 	pc = nextSibling(pc);
590 	pn = nextSibling(pn);
591       }
592       Setattr(n, "templateparms", Getattr(cn, "templateparms"));
593     }
594     Setattr(ccurrent, name, n);
595 
596   } else if (cn && (Getattr(n, "sym:weak"))) {
597     /* The node being added is weak.  Don't worry about it */
598   } else if (cn && (Getattr(n, "sym:typename"))) {
599     /* The node being added is a typename.  We definitely add it */
600     Setattr(ccurrent, name, n);
601     append = cn;
602   } else if (cn && (Checkattr(cn, "nodeType", "templateparm"))) {
603     Swig_error(Getfile(n), Getline(n), "Declaration of '%s' shadows template parameter,\n", name);
604     Swig_error(Getfile(cn), Getline(cn), "previous template parameter declaration '%s'.\n", name);
605     return;
606   } else if (cn) {
607     append = n;
608   } else if (!cn) {
609     /* No conflict. Add the symbol */
610     Setattr(ccurrent, name, n);
611   }
612 
613   /* Multiple entries in the C symbol table.   We append to the symbol table */
614   if (append) {
615     Node *fn, *pn = 0;
616     cn = Getattr(ccurrent, name);
617     fn = cn;
618     while (fn) {
619       pn = fn;
620       if (fn == append) {
621 	/* already added. Bail */
622 	return;
623       }
624       fn = Getattr(fn, "csym:nextSibling");
625     }
626     if (pn) {
627       Setattr(pn, "csym:nextSibling", append);
628     }
629   }
630 
631   /* Special typedef handling.  When a typedef node is added to the symbol table, we
632      might have to add a type alias.   This would occur if the typedef mapped to another
633      scope in the system.  For example:
634 
635      class Foo {
636      };
637 
638      typedef Foo OtherFoo;
639 
640      In this case, OtherFoo becomes an alias for Foo. */
641 
642   {
643     Node *td = n;
644     while (td && Checkattr(td, "nodeType", "cdecl") && Checkattr(td, "storage", "typedef")) {
645       SwigType *type;
646       Node *td1;
647       type = Copy(Getattr(td, "type"));
648       SwigType_push(type, Getattr(td, "decl"));
649       td1 = Swig_symbol_clookup(type, 0);
650 
651       /* Fix pathetic case #1214313:
652 
653          class Foo
654          {
655          };
656 
657          typedef Foo FooBar;
658 
659          class CBaz
660          {
661          public:
662          typedef FooBar Foo;
663          };
664 
665          ie, when Foo -> FooBar -> Foo, jump one scope up when possible.
666 
667        */
668       if (td1 && Checkattr(td1, "storage", "typedef")) {
669 	String *st = Getattr(td1, "type");
670 	String *sn = Getattr(td, "name");
671 	if (st && sn && Equal(st, sn)) {
672 	  Symtab *sc = Getattr(current_symtab, "parentNode");
673 	  if (sc)
674 	    td1 = Swig_symbol_clookup(type, sc);
675 	}
676       }
677 
678       Delete(type);
679       if (td1 == td)
680 	break;
681       td = td1;
682       if (td) {
683 	Symtab *st = Getattr(td, "symtab");
684 	if (st) {
685 	  Swig_symbol_alias(Getattr(n, "name"), st);
686 	  break;
687 	}
688       }
689     }
690   }
691 }
692 
693 /* -----------------------------------------------------------------------------
694  * Swig_symbol_add()
695  *
696  * Adds a node to the symbol table.  Returns the node itself if successfully
697  * added.  Otherwise, it returns the symbol table entry of the conflicting node.
698  *
699  * Also places the symbol in a behind-the-scenes C symbol table.  This is needed
700  * for namespace support, type resolution, and other issues.
701  * ----------------------------------------------------------------------------- */
702 
Swig_symbol_add(const_String_or_char_ptr symname,Node * n)703 Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
704   Hash *c, *cl = 0;
705   SwigType *decl, *ndecl;
706   String *cstorage, *nstorage;
707   int nt = 0, ct = 0;
708   int pn = 0;
709   int u1 = 0, u2 = 0;
710   String *name, *overname;
711 
712   /* See if the node has a name.  If so, we place in the C symbol table for this
713      scope. We don't worry about overloading here---the primary purpose of this
714      is to record information for type/name resolution for later. Conflicts
715      in C namespaces are errors, but these will be caught by the C++ compiler
716      when compiling the wrapper code */
717 
718 
719   /* There are a few options for weak symbols.  A "weak" symbol
720      is any symbol that can be replaced by another symbol in the C symbol
721      table.  An example would be a forward class declaration.  A forward
722      class sits in the symbol table until a real class declaration comes along.
723 
724      Certain symbols are marked as "sym:typename".  These are important
725      symbols related to the C++ type-system and take precedence in the C
726      symbol table.  An example might be code like this:
727 
728      template<class T> T foo(T x);
729      int foo(int);
730 
731      In this case, the template is marked with "sym:typename" so that it
732      stays in the C symbol table (so that it can be expanded using %template).
733    */
734 
735   name = Getattr(n, "name");
736   if (name && Len(name)) {
737     Swig_symbol_cadd(name, n);
738   }
739 
740   /* No symbol name defined.  We return. */
741   if (!symname) {
742     Setattr(n, "sym:symtab", current_symtab);
743     return n;
744   }
745 
746   /* If node is ignored. We don't proceed any further */
747   if (GetFlag(n, "feature:ignore"))
748     return n;
749 
750   /* See if the symbol already exists in the table */
751   c = Getattr(current, symname);
752 
753   /* Check for a weak symbol.  A weak symbol is allowed to be in the
754      symbol table, but is silently overwritten by other symbols.  An example
755      would be a forward class declaration.  For instance:
756 
757      class Foo;
758 
759      In this case, "Foo" sits in the symbol table.  However, the
760      definition of Foo would replace the entry if it appeared later. */
761 
762   if (c && Getattr(c, "sym:weak")) {
763     c = 0;
764   }
765   if (c) {
766     /* There is a symbol table conflict.  There are a few cases to consider here:
767        (1) A conflict between a class/enum and a typedef declaration is okay.
768        In this case, the symbol table entry is set to the class/enum declaration
769        itself, not the typedef.
770        (2) A conflict between namespaces is okay--namespaces are open
771        (3) Otherwise, overloading is only allowed for functions
772        (4) This special case is okay: a class template instantiated with same name as the template's name
773      */
774 
775     /* Check for namespaces */
776     String *ntype = Getattr(n, "nodeType");
777     if ((Equal(ntype, Getattr(c, "nodeType"))) && ((Equal(ntype, "namespace")))) {
778       Node *cl, *pcl = 0;
779       cl = c;
780       while (cl) {
781 	pcl = cl;
782 	cl = Getattr(cl, "sym:nextSibling");
783       }
784       Setattr(pcl, "sym:nextSibling", n);
785       Setattr(n, "sym:symtab", current_symtab);
786       Setattr(n, "sym:name", symname);
787       Setattr(n, "sym:previousSibling", pcl);
788       return n;
789     }
790 
791     /* Special case: class template instantiated with same name as the template's name eg: %template(X) X<int>; */
792     if (Equal(nodeType(c), "template")) {
793       String *nt1 = Getattr(c, "templatetype");
794       String *nt2 = nodeType(n);
795       if (Equal(nt1, "class") && Equal(nt1, nt2)) {
796 	if (Getattr(n, "template")) {
797 	  /* Finally check that another %template with same name doesn't already exist */
798 	  if (!Getattr(c, "sym:nextSibling")) {
799 	    Setattr(c, "sym:nextSibling", n);
800 	    Setattr(n, "sym:symtab", current_symtab);
801 	    Setattr(n, "sym:name", symname);
802 	    Setattr(n, "sym:previousSibling", c);
803 	    return n;
804 	  }
805 	}
806       }
807     }
808 
809     if (Getattr(n, "allows_typedef"))
810       nt = 1;
811     if (Getattr(c, "allows_typedef"))
812       ct = 1;
813     if (nt || ct) {
814       Node *td, *other;
815       String *s;
816       /* At least one of the nodes allows typedef overloading.  Make sure that
817          both don't--this would be a conflict */
818 
819       if (nt && ct)
820 	return c;
821 
822       /* Figure out which node allows the typedef */
823       if (nt) {
824 	td = n;
825 	other = c;
826       } else {
827 	td = c;
828 	other = n;
829       }
830       /* Make sure the other node is a typedef */
831       s = Getattr(other, "storage");
832       if (!s || (!Equal(s, "typedef")))
833 	return c;		/* No.  This is a conflict */
834 
835       /* Hmmm.  This appears to be okay.  Make sure the symbol table refers to the allow_type node */
836 
837       if (td != c) {
838 	Setattr(current, symname, td);
839 	Setattr(td, "sym:symtab", current_symtab);
840 	Setattr(td, "sym:name", symname);
841       }
842       return n;
843     }
844 
845     decl = Getattr(c, "decl");
846     ndecl = Getattr(n, "decl");
847 
848     {
849       String *nt1, *nt2;
850       nt1 = Getattr(n, "nodeType");
851       if (Equal(nt1, "template"))
852 	nt1 = Getattr(n, "templatetype");
853       nt2 = Getattr(c, "nodeType");
854       if (Equal(nt2, "template"))
855 	nt2 = Getattr(c, "templatetype");
856       if (Equal(nt1, "using"))
857 	u1 = 1;
858       if (Equal(nt2, "using"))
859 	u2 = 1;
860 
861       if ((!Equal(nt1, nt2)) && !(u1 || u2))
862 	return c;
863     }
864     if (!(u1 || u2)) {
865       if ((!SwigType_isfunction(decl)) || (!SwigType_isfunction(ndecl))) {
866 	/* Symbol table conflict */
867 	return c;
868       }
869     }
870 
871     /* Hmmm. Declarator seems to indicate that this is a function */
872     /* Look at storage class to see if compatible */
873     cstorage = Getattr(c, "storage");
874     nstorage = Getattr(n, "storage");
875 
876     /* If either one is declared as typedef, forget it. We're hosed */
877     if (Cmp(cstorage, "typedef") == 0) {
878       return c;
879     }
880     if (Cmp(nstorage, "typedef") == 0) {
881       return c;
882     }
883 
884     /* Okay. Walk down the list of symbols and see if we get a declarator match */
885     {
886       String *nt = Getattr(n, "nodeType");
887       int n_template = Equal(nt, "template") && Checkattr(n, "templatetype", "cdecl");
888       int n_plain_cdecl = Equal(nt, "cdecl");
889       Node *cn = c;
890       pn = 0;
891       while (cn) {
892 	decl = Getattr(cn, "decl");
893 	if (!(u1 || u2)) {
894 	  if (Cmp(ndecl, decl) == 0) {
895 	    /* Declarator conflict */
896 	    /* Now check we don't have a non-templated function overloaded by a templated function with same params,
897 	     * eg void foo(); template<typename> void foo(); */
898 	    String *cnt = Getattr(cn, "nodeType");
899 	    int cn_template = Equal(cnt, "template") && Checkattr(cn, "templatetype", "cdecl");
900 	    int cn_plain_cdecl = Equal(cnt, "cdecl");
901 	    if (!((n_template && cn_plain_cdecl) || (cn_template && n_plain_cdecl))) {
902 	      /* found a conflict */
903 	      return cn;
904 	    }
905 	  }
906 	}
907 	cl = cn;
908 	cn = Getattr(cn, "sym:nextSibling");
909 	pn++;
910       }
911     }
912     /* Well, we made it this far.  Guess we can drop the symbol in place */
913     Setattr(n, "sym:symtab", current_symtab);
914     Setattr(n, "sym:name", symname);
915     /* Printf(stdout,"%s %p\n", Getattr(n,"sym:overname"), current_symtab); */
916     assert(!Getattr(n, "sym:overname"));
917     overname = NewStringf("__SWIG_%d", pn);
918     Setattr(n, "sym:overname", overname);
919     /*Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */
920     Setattr(cl, "sym:nextSibling", n);
921     Setattr(n, "sym:previousSibling", cl);
922     Setattr(cl, "sym:overloaded", c);
923     Setattr(n, "sym:overloaded", c);
924     Delete(overname);
925     return n;
926   }
927 
928   /* No conflict.  Just add it */
929   Setattr(n, "sym:symtab", current_symtab);
930   Setattr(n, "sym:name", symname);
931   /* Printf(stdout,"%s\n", Getattr(n,"sym:overname")); */
932   overname = NewStringf("__SWIG_%d", pn);
933   Setattr(n, "sym:overname", overname);
934   Delete(overname);
935   /* Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */
936   Setattr(current, symname, n);
937   return n;
938 }
939 
940 /* -----------------------------------------------------------------------------
941  * symbol_lookup()
942  *
943  * Internal function to handle fully qualified symbol table lookups.  This
944  * works from the symbol table supplied in symtab and unwinds its way out
945  * towards the global scope.
946  *
947  * This function operates in the C namespace, not the target namespace.
948  *
949  * The check function is an optional callback that can be used to verify a particular
950  * symbol match.   This is only used in some of the more exotic parts of SWIG. For instance,
951  * verifying that a class hierarchy implements all pure virtual methods.
952  * ----------------------------------------------------------------------------- */
953 
_symbol_lookup(const String * name,Symtab * symtab,int (* check)(Node * n))954 static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (Node *n)) {
955   Node *n;
956   List *inherit;
957   Hash *sym = Getattr(symtab, "csymtab");
958   if (Getmark(symtab))
959     return 0;
960   Setmark(symtab, 1);
961 
962   n = Getattr(sym, name);
963 
964 #ifdef SWIG_DEBUG
965   Printf(stderr, "symbol_look %s %p %p %s\n", name, n, symtab, Getattr(symtab, "name"));
966 #endif
967 
968   if (n) {
969     /* if a check-function is defined.  Call it to determine a match */
970     if (check) {
971       int c = check(n);
972       if (c == 1) {
973 	Setmark(symtab, 0);
974 	return n;
975       }
976       if (c < 0) {
977 	/* Terminate the search right away */
978 	Setmark(symtab, 0);
979 	return 0;
980       }
981     } else {
982       Setmark(symtab, 0);
983       return n;
984     }
985   }
986 
987   if (!n && SwigType_istemplate(name)) {
988     String *dname = 0;
989     Setmark(symtab, 0);
990     dname = Swig_symbol_template_deftype(name, symtab);
991     if (!Equal(dname, name)) {
992       n = _symbol_lookup(dname, symtab, check);
993     }
994     Delete(dname);
995     if (n)
996       return n;
997     Setmark(symtab, 1);
998   }
999 
1000   inherit = Getattr(symtab, "inherit");
1001   if (inherit && use_inherit) {
1002     int i, len;
1003     len = Len(inherit);
1004     for (i = 0; i < len; i++) {
1005       n = _symbol_lookup(name, Getitem(inherit, i), check);
1006       if (n) {
1007 	Setmark(symtab, 0);
1008 	return n;
1009       }
1010     }
1011   }
1012 
1013   Setmark(symtab, 0);
1014   return 0;
1015 }
1016 
symbol_lookup(const_String_or_char_ptr name,Symtab * symtab,int (* check)(Node * n))1017 static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*check) (Node *n)) {
1018   Node *n = 0;
1019   if (DohCheck(name)) {
1020     n = _symbol_lookup(name, symtab, check);
1021   } else {
1022     String *sname = NewString(name);
1023     n = _symbol_lookup(sname, symtab, check);
1024     Delete(sname);
1025   }
1026   return n;
1027 }
1028 
1029 
1030 
1031 /* -----------------------------------------------------------------------------
1032  * symbol_lookup_qualified()
1033  * ----------------------------------------------------------------------------- */
1034 
symbol_lookup_qualified(const_String_or_char_ptr name,Symtab * symtab,const String * prefix,int local,int (* checkfunc)(Node * n))1035 static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, int (*checkfunc) (Node *n)) {
1036   /* This is a little funky, we search by fully qualified names */
1037 
1038   if (!symtab)
1039     return 0;
1040   if (!prefix) {
1041     Node *n;
1042     String *bname = 0;
1043     String *prefix = 0;
1044     Swig_scopename_split(name, &prefix, &bname);
1045     n = symbol_lookup_qualified(bname, symtab, prefix, local, checkfunc);
1046     Delete(bname);
1047     Delete(prefix);
1048     return n;
1049   } else {
1050     Symtab *st;
1051     Node *n = 0;
1052     /* Make qualified name of current scope */
1053     String *qalloc = 0;
1054     String *qname = Swig_symbol_qualifiedscopename(symtab);
1055     const String *cqname;
1056     if (qname) {
1057       if (Len(qname)) {
1058 	if (prefix && Len(prefix)) {
1059 	  Printv(qname, "::", prefix, NIL);
1060 	}
1061       } else {
1062 	Append(qname, prefix);
1063       }
1064       qalloc = qname;
1065       cqname = qname;
1066     } else {
1067       cqname = prefix;
1068     }
1069     st = Getattr(symtabs, cqname);
1070     /* Found a scope match */
1071     if (st) {
1072       if (!name) {
1073 	if (qalloc)
1074 	  Delete(qalloc);
1075 	return st;
1076       }
1077       n = symbol_lookup(name, st, checkfunc);
1078     }
1079     if (qalloc)
1080       Delete(qalloc);
1081 
1082     if (!n) {
1083       if (!local) {
1084 	Node *pn = Getattr(symtab, "parentNode");
1085 	if (pn)
1086 	  n = symbol_lookup_qualified(name, pn, prefix, local, checkfunc);
1087 
1088 	/* Check inherited scopes */
1089 	if (!n) {
1090 	  List *inherit = Getattr(symtab, "inherit");
1091 	  if (inherit && use_inherit) {
1092 	    int i, len;
1093 	    len = Len(inherit);
1094 	    for (i = 0; i < len; i++) {
1095 	      Node *prefix_node = symbol_lookup(prefix, Getitem(inherit, i), checkfunc);
1096 	      if (prefix_node) {
1097 		Node *prefix_symtab = Getattr(prefix_node, "symtab");
1098 		if (prefix_symtab) {
1099 		  n = symbol_lookup(name, prefix_symtab, checkfunc);
1100 		  break;
1101 		}
1102 	      }
1103 	    }
1104 	  }
1105 	}
1106       } else {
1107 	n = 0;
1108       }
1109     }
1110     return n;
1111   }
1112 }
1113 
1114 /* -----------------------------------------------------------------------------
1115  * Swig_symbol_clookup()
1116  *
1117  * Look up a symbol in the symbol table.   This uses the C name, not scripting
1118  * names.   Note: If we come across a using declaration, we follow it to
1119  * to get the real node. Any using directives are also followed (but this is
1120  * implemented in symbol_lookup()).
1121  * ----------------------------------------------------------------------------- */
1122 
Swig_symbol_clookup(const_String_or_char_ptr name,Symtab * n)1123 Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) {
1124   Hash *hsym = 0;
1125   Node *s = 0;
1126 
1127   if (!n) {
1128     hsym = current_symtab;
1129   } else {
1130     if (!Checkattr(n, "nodeType", "symboltable")) {
1131       n = Getattr(n, "sym:symtab");
1132     }
1133     assert(n);
1134     if (n) {
1135       hsym = n;
1136     }
1137   }
1138 
1139   if (Swig_scopename_check(name)) {
1140     char *cname = Char(name);
1141     if (strncmp(cname, "::", 2) == 0) {
1142       String *nname = NewString(cname + 2);
1143       if (Swig_scopename_check(nname)) {
1144 	s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
1145       } else {
1146 	s = symbol_lookup(nname, global_scope, 0);
1147       }
1148       Delete(nname);
1149     } else {
1150       String *prefix = Swig_scopename_prefix(name);
1151       if (prefix) {
1152 	s = symbol_lookup_qualified(name, hsym, 0, 0, 0);
1153 	Delete(prefix);
1154 	if (!s) {
1155 	  return 0;
1156 	}
1157       }
1158     }
1159   }
1160   if (!s) {
1161     while (hsym) {
1162       s = symbol_lookup(name, hsym, 0);
1163       if (s)
1164 	break;
1165       hsym = Getattr(hsym, "parentNode");
1166       if (!hsym)
1167 	break;
1168     }
1169   }
1170 
1171   if (!s) {
1172     return 0;
1173   }
1174   /* Check if s is a 'using' node */
1175   while (s && Checkattr(s, "nodeType", "using")) {
1176     String *uname = Getattr(s, "uname");
1177     Symtab *un = Getattr(s, "sym:symtab");
1178     Node *ss = (!Equal(name, uname) || (un != n)) ? Swig_symbol_clookup(uname, un) : 0;	/* avoid infinity loop */
1179     if (!ss) {
1180       Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
1181     }
1182     s = ss;
1183   }
1184   return s;
1185 }
1186 
1187 /* -----------------------------------------------------------------------------
1188  * Swig_symbol_clookup_check()
1189  *
1190  * This function is identical to Swig_symbol_clookup() except that it
1191  * accepts a callback function that is invoked to determine a symbol match.
1192  * The purpose of this function is to support complicated algorithms that need
1193  * to examine multiple definitions of the same symbol that might appear in an
1194  * inheritance hierarchy.
1195  * ----------------------------------------------------------------------------- */
1196 
Swig_symbol_clookup_check(const_String_or_char_ptr name,Symtab * n,int (* checkfunc)(Node * n))1197 Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *n)) {
1198   Hash *hsym = 0;
1199   Node *s = 0;
1200 
1201   if (!n) {
1202     hsym = current_symtab;
1203   } else {
1204     if (!Checkattr(n, "nodeType", "symboltable")) {
1205       n = Getattr(n, "sym:symtab");
1206     }
1207     assert(n);
1208     if (n) {
1209       hsym = n;
1210     }
1211   }
1212 
1213   if (Swig_scopename_check(name)) {
1214     char *cname = Char(name);
1215     if (strncmp(cname, "::", 2) == 0) {
1216       String *nname = NewString(cname + 2);
1217       if (Swig_scopename_check(nname)) {
1218 	s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
1219       } else {
1220 	s = symbol_lookup(nname, global_scope, checkfunc);
1221       }
1222       Delete(nname);
1223     } else {
1224       String *prefix = Swig_scopename_prefix(name);
1225       if (prefix) {
1226 	s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc);
1227 	Delete(prefix);
1228 	if (!s) {
1229 	  return 0;
1230 	}
1231       }
1232     }
1233   }
1234   if (!s) {
1235     while (hsym) {
1236       s = symbol_lookup(name, hsym, checkfunc);
1237       if (s)
1238 	break;
1239       hsym = Getattr(hsym, "parentNode");
1240       if (!hsym)
1241 	break;
1242     }
1243   }
1244   if (!s) {
1245     return 0;
1246   }
1247   /* Check if s is a 'using' node */
1248   while (s && Checkattr(s, "nodeType", "using")) {
1249     Node *ss;
1250     ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
1251     if (!ss && !checkfunc) {
1252       Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
1253     }
1254     s = ss;
1255   }
1256   return s;
1257 }
1258 
1259 /* -----------------------------------------------------------------------------
1260  * Swig_symbol_clookup_local()
1261  *
1262  * Same as Swig_symbol_clookup but parent nodes are not searched, that is, just
1263  * this symbol table is searched.
1264  * ----------------------------------------------------------------------------- */
1265 
Swig_symbol_clookup_local(const_String_or_char_ptr name,Symtab * n)1266 Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) {
1267   Hash *hsym;
1268   Node *s = 0;
1269 
1270   if (!n) {
1271     hsym = current_symtab;
1272   } else {
1273     if (!Checkattr(n, "nodeType", "symboltable")) {
1274       n = Getattr(n, "sym:symtab");
1275     }
1276     assert(n);
1277     hsym = n;
1278   }
1279 
1280   if (Swig_scopename_check(name)) {
1281     char *cname = Char(name);
1282     if (strncmp(cname, "::", 2) == 0) {
1283       String *nname = NewString(cname + 2);
1284       if (Swig_scopename_check(nname)) {
1285 	s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
1286       } else {
1287 	s = symbol_lookup(nname, global_scope, 0);
1288       }
1289       Delete(nname);
1290     } else {
1291       s = symbol_lookup_qualified(name, hsym, 0, 0, 0);
1292     }
1293   }
1294   if (!s) {
1295     s = symbol_lookup(name, hsym, 0);
1296   }
1297   if (!s)
1298     return 0;
1299   /* Check if s is a 'using' node */
1300   while (s && Checkattr(s, "nodeType", "using")) {
1301     Node *ss = Swig_symbol_clookup_local(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
1302     if (!ss) {
1303       Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
1304     }
1305     s = ss;
1306   }
1307   return s;
1308 }
1309 
1310 /* -----------------------------------------------------------------------------
1311  * Swig_symbol_clookup_local_check()
1312  * ----------------------------------------------------------------------------- */
1313 
Swig_symbol_clookup_local_check(const_String_or_char_ptr name,Symtab * n,int (* checkfunc)(Node *))1314 Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) {
1315   Hash *hsym;
1316   Node *s = 0;
1317 
1318   if (!n) {
1319     hsym = current_symtab;
1320   } else {
1321     if (!Checkattr(n, "nodeType", "symboltable")) {
1322       n = Getattr(n, "sym:symtab");
1323     }
1324     assert(n);
1325     hsym = n;
1326   }
1327 
1328   if (Swig_scopename_check(name)) {
1329     char *cname = Char(name);
1330     if (strncmp(cname, "::", 2) == 0) {
1331       String *nname = NewString(cname + 2);
1332       if (Swig_scopename_check(nname)) {
1333 	s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
1334       } else {
1335 	s = symbol_lookup(nname, global_scope, checkfunc);
1336       }
1337       Delete(nname);
1338     } else {
1339       s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc);
1340     }
1341   }
1342   if (!s) {
1343     s = symbol_lookup(name, hsym, checkfunc);
1344   }
1345   if (!s)
1346     return 0;
1347   /* Check if s is a 'using' node */
1348   while (s && Checkattr(s, "nodeType", "using")) {
1349     Node *ss = Swig_symbol_clookup_local_check(Getattr(s, "uname"), Getattr(s, "sym:symtab"), checkfunc);
1350     if (!ss && !checkfunc) {
1351       Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
1352     }
1353     s = ss;
1354   }
1355   return s;
1356 }
1357 
1358 /* -----------------------------------------------------------------------------
1359  * Swig_symbol_clookup_no_inherit()
1360  *
1361  * Symbol lookup like Swig_symbol_clookup but does not follow using declarations.
1362  * ----------------------------------------------------------------------------- */
1363 
Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name,Symtab * n)1364 Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) {
1365   Node *s = 0;
1366   assert(use_inherit==1);
1367   use_inherit = 0;
1368   s = Swig_symbol_clookup(name, n);
1369   use_inherit = 1;
1370   return s;
1371 }
1372 
1373 /* -----------------------------------------------------------------------------
1374  * Swig_symbol_cscope()
1375  *
1376  * Look up a scope name.
1377  * ----------------------------------------------------------------------------- */
1378 
Swig_symbol_cscope(const_String_or_char_ptr name,Symtab * symtab)1379 Symtab *Swig_symbol_cscope(const_String_or_char_ptr name, Symtab *symtab) {
1380   char *cname = Char(name);
1381   if (strncmp(cname, "::", 2) == 0)
1382     return symbol_lookup_qualified(0, global_scope, name, 0, 0);
1383   return symbol_lookup_qualified(0, symtab, name, 0, 0);
1384 }
1385 
1386 /* -----------------------------------------------------------------------------
1387  * Swig_symbol_remove()
1388  *
1389  * Remove a symbol. If the symbol is an overloaded function and the symbol removed
1390  * is not the last in the list of overloaded functions, then the overloaded
1391  * names (sym:overname attribute) are changed to start from zero, eg __SWIG_0.
1392  * ----------------------------------------------------------------------------- */
1393 
Swig_symbol_remove(Node * n)1394 void Swig_symbol_remove(Node *n) {
1395   Symtab *symtab;
1396   String *symname;
1397   String *overname;
1398   Node *symprev;
1399   Node *symnext;
1400   Node *fixovername = 0;
1401   symtab = Getattr(n, "sym:symtab");	/* Get symbol table object */
1402   symtab = Getattr(symtab, "symtab");	/* Get actual hash table of symbols */
1403   symname = Getattr(n, "sym:name");
1404   symprev = Getattr(n, "sym:previousSibling");
1405   symnext = Getattr(n, "sym:nextSibling");
1406 
1407   /* If previous symbol, just fix the links */
1408   if (symprev) {
1409     if (symnext) {
1410       Setattr(symprev, "sym:nextSibling", symnext);
1411       fixovername = symprev;	/* fix as symbol to remove is somewhere in the middle of the linked list */
1412     } else {
1413       Delattr(symprev, "sym:nextSibling");
1414     }
1415   } else {
1416     /* If no previous symbol, see if there is a next symbol */
1417     if (symnext) {
1418       Setattr(symtab, symname, symnext);
1419       fixovername = symnext;	/* fix as symbol to remove is at head of linked list */
1420     } else {
1421       if (symname)
1422 	Delattr(symtab, symname);
1423     }
1424   }
1425   if (symnext) {
1426     if (symprev) {
1427       Setattr(symnext, "sym:previousSibling", symprev);
1428     } else {
1429       Delattr(symnext, "sym:previousSibling");
1430     }
1431   }
1432   Delattr(n, "sym:symtab");
1433   Delattr(n, "sym:previousSibling");
1434   Delattr(n, "sym:nextSibling");
1435   Delattr(n, "csym:nextSibling");
1436   Delattr(n, "sym:overname");
1437   Delattr(n, "csym:previousSibling");
1438   Delattr(n, "sym:overloaded");
1439   n = 0;
1440 
1441   if (fixovername) {
1442     Node *nn = fixovername;
1443     Node *head = fixovername;
1444     int pn = 0;
1445 
1446     /* find head of linked list */
1447     while (nn) {
1448       head = nn;
1449       nn = Getattr(nn, "sym:previousSibling");
1450     }
1451 
1452     /* adjust all the sym:overname strings to start from 0 and increment by one */
1453     nn = head;
1454     while (nn) {
1455       assert(Getattr(nn, "sym:overname"));
1456       Delattr(nn, "sym:overname");
1457       overname = NewStringf("__SWIG_%d", pn);
1458       Setattr(nn, "sym:overname", overname);
1459       Delete(overname);
1460       pn++;
1461       nn = Getattr(nn, "sym:nextSibling");
1462     }
1463   }
1464 }
1465 
1466 /* -----------------------------------------------------------------------------
1467  * Swig_symbol_qualified()
1468  *
1469  * Return the qualified name of a symbol
1470  * ----------------------------------------------------------------------------- */
1471 
Swig_symbol_qualified(Node * n)1472 String *Swig_symbol_qualified(Node *n) {
1473   Hash *symtab;
1474   if (Checkattr(n, "nodeType", "symboltable")) {
1475     symtab = n;
1476   } else {
1477     symtab = Getattr(n, "sym:symtab");
1478   }
1479   if (!symtab)
1480     return NewStringEmpty();
1481 #ifdef SWIG_DEBUG
1482   Printf(stderr, "symbol_qscope %s %p %s\n", Getattr(n, "name"), symtab, Getattr(symtab, "name"));
1483 #endif
1484   return Swig_symbol_qualifiedscopename(symtab);
1485 }
1486 
1487 /* -----------------------------------------------------------------------------
1488  * Swig_symbol_isoverloaded()
1489  *
1490  * Check if a symbol is overloaded.  Returns the first symbol if so.
1491  * ----------------------------------------------------------------------------- */
1492 
Swig_symbol_isoverloaded(Node * n)1493 Node *Swig_symbol_isoverloaded(Node *n) {
1494   return Getattr(n, "sym:overloaded");
1495 }
1496 
1497 /* -----------------------------------------------------------------------------
1498  * symbol_template_qualify()
1499  *
1500  * Internal function to create a fully qualified type name for templates
1501  * ----------------------------------------------------------------------------- */
1502 
1503 /* This cache produces problems with OSS, don't active it */
1504 /* #define SWIG_TEMPLATE_QUALIFY_CACHE */
symbol_template_qualify(const SwigType * e,Symtab * st)1505 static SwigType *symbol_template_qualify(const SwigType *e, Symtab *st) {
1506   String *tprefix, *tsuffix;
1507   SwigType *qprefix;
1508   List *targs;
1509   Node *tempn;
1510   Symtab *tscope;
1511   Iterator ti;
1512 #ifdef SWIG_TEMPLATE_QUALIFY_CACHE
1513   static Hash *qualify_cache = 0;
1514   String *scopetype = st ? NewStringf("%s::%s", Getattr(st, "name"), e)
1515       : NewStringf("%s::%s", Swig_symbol_getscopename(), e);
1516   if (!qualify_cache) {
1517     qualify_cache = NewHash();
1518   }
1519   if (scopetype) {
1520     String *cres = Getattr(qualify_cache, scopetype);
1521     if (cres) {
1522       Delete(scopetype);
1523       return Copy(cres);
1524     }
1525   }
1526 #endif
1527 
1528   tprefix = SwigType_templateprefix(e);
1529   tsuffix = SwigType_templatesuffix(e);
1530   qprefix = Swig_symbol_type_qualify(tprefix, st);
1531   targs = SwigType_parmlist(e);
1532   tempn = Swig_symbol_clookup_local(tprefix, st);
1533   tscope = tempn ? Getattr(tempn, "sym:symtab") : 0;
1534   Append(qprefix, "<(");
1535   for (ti = First(targs); ti.item;) {
1536     String *vparm;
1537     String *qparm = Swig_symbol_type_qualify(ti.item, st);
1538     if (tscope && (tscope != st)) {
1539       String *ty = Swig_symbol_type_qualify(qparm, tscope);
1540       Delete(qparm);
1541       qparm = ty;
1542     }
1543 
1544     vparm = Swig_symbol_template_param_eval(qparm, st);
1545     Append(qprefix, vparm);
1546     ti = Next(ti);
1547     if (ti.item) {
1548       Putc(',', qprefix);
1549     }
1550     Delete(qparm);
1551     Delete(vparm);
1552   }
1553   Append(qprefix, ")>");
1554   Append(qprefix, tsuffix);
1555   Delete(tprefix);
1556   Delete(tsuffix);
1557   Delete(targs);
1558 #ifdef SWIG_DEBUG
1559   Printf(stderr, "symbol_temp_qual %s %s\n", e, qprefix);
1560 #endif
1561 #ifdef SWIG_TEMPLATE_QUALIFY_CACHE
1562   Setattr(qualify_cache, scopetype, qprefix);
1563   Delete(scopetype);
1564 #endif
1565 
1566   return qprefix;
1567 }
1568 
1569 
symbol_no_constructor(Node * n)1570 static int symbol_no_constructor(Node *n) {
1571   return !Checkattr(n, "nodeType", "constructor");
1572 }
1573 
1574 /* -----------------------------------------------------------------------------
1575  * Swig_symbol_type_qualify()
1576  *
1577  * Create a fully qualified type name
1578  * Note: Does not resolve a constructor if passed in as the 'type'.
1579  * ----------------------------------------------------------------------------- */
1580 
Swig_symbol_type_qualify(const SwigType * t,Symtab * st)1581 SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) {
1582   List *elements;
1583   String *result = NewStringEmpty();
1584   int i, len;
1585   char *c = Char(t);
1586   if (strncmp(c, "::", 2) == 0) {
1587     Append(result, t);
1588     return result;
1589   }
1590 
1591   elements = SwigType_split(t);
1592 
1593   len = Len(elements);
1594   for (i = 0; i < len; i++) {
1595     String *e = Getitem(elements, i);
1596     if (SwigType_issimple(e)) {
1597       /* Note: the unary scope operator (::) is being removed from the template parameters here. */
1598       Node *n = Swig_symbol_clookup_check(e, st, symbol_no_constructor);
1599       if (n) {
1600 	String *name = Getattr(n, "name");
1601 	Clear(e);
1602 	Append(e, name);
1603 #ifdef SWIG_DEBUG
1604 	Printf(stderr, "symbol_qual_ei %d %s %s %p\n", i, name, e, st);
1605 #endif
1606 	if (!Swig_scopename_check(name)) {
1607 	  String *qname = Swig_symbol_qualified(n);
1608 	  if (qname && Len(qname)) {
1609 	    Insert(e, 0, "::");
1610 	    Insert(e, 0, qname);
1611 	  }
1612 #ifdef SWIG_DEBUG
1613 	  Printf(stderr, "symbol_qual_sc %d %s %s %p\n", i, qname, e, st);
1614 #endif
1615 	  Delete(qname);
1616 	}
1617       } else if (SwigType_istemplate(e)) {
1618 	SwigType *ty = symbol_template_qualify(e, st);
1619 	Clear(e);
1620 	Append(e, ty);
1621 	Delete(ty);
1622       }
1623       if (strncmp(Char(e), "::", 2) == 0) {
1624 	Delitem(e, 0);
1625 	Delitem(e, 0);
1626       }
1627       Append(result, e);
1628     } else if (SwigType_isfunction(e)) {
1629       List *parms = SwigType_parmlist(e);
1630       String *s = NewString("f(");
1631       Iterator pi = First(parms);
1632       while (pi.item) {
1633 	String *pf = Swig_symbol_type_qualify(pi.item, st);
1634 	Append(s, pf);
1635 	pi = Next(pi);
1636 	if (pi.item) {
1637 	  Append(s, ",");
1638 	}
1639 	Delete(pf);
1640       }
1641       Append(s, ").");
1642       Append(result, s);
1643       Delete(parms);
1644       Delete(s);
1645     } else {
1646       Append(result, e);
1647     }
1648   }
1649   Delete(elements);
1650 #ifdef SWIG_DEBUG
1651   Printf(stderr, "symbol_qualify %s %s %p %s\n", t, result, st, st ? Getattr(st, "name") : 0);
1652 #endif
1653 
1654   return result;
1655 }
1656 
1657 /* -----------------------------------------------------------------------------
1658  * Swig_symbol_template_reduce()
1659  * Resolves template parameter types
1660  * For example:
1661  *   typedef int Int;
1662  *   typedef Int Integer;
1663  * with input:
1664  *   Foo<(Int,Integer)>
1665  * returns:
1666  *   Foo<(int,int)>
1667  * ----------------------------------------------------------------------------- */
1668 
1669 static
Swig_symbol_template_reduce(SwigType * qt,Symtab * ntab)1670 SwigType *Swig_symbol_template_reduce(SwigType *qt, Symtab *ntab) {
1671   Parm *p;
1672   String *templateargs = SwigType_templateargs(qt);
1673   List *parms = SwigType_parmlist(templateargs);
1674   Iterator pi = First(parms);
1675   String *tprefix = SwigType_templateprefix(qt);
1676   String *tsuffix = SwigType_templatesuffix(qt);
1677   String *qprefix = SwigType_typedef_qualified(tprefix);
1678   Append(qprefix, "<(");
1679   while ((p = pi.item)) {
1680     String *np;
1681     String *tp = Swig_symbol_typedef_reduce(p, ntab);
1682     String *qp = Swig_symbol_type_qualify(tp, ntab);
1683     Node *n = Swig_symbol_clookup(qp, ntab);
1684     if (n) {
1685       String *qual = Swig_symbol_qualified(n);
1686       np = Copy(Getattr(n, "name"));
1687       Delete(tp);
1688       tp = np;
1689       if (qual && Len(qual)) {
1690 	Insert(np, 0, "::");
1691 	Insert(np, 0, qual);
1692       }
1693       Delete(qual);
1694     } else {
1695       np = qp;
1696     }
1697     Append(qprefix, np);
1698     pi = Next(pi);
1699     if (pi.item) {
1700       Append(qprefix, ",");
1701     }
1702     Delete(qp);
1703     Delete(tp);
1704   }
1705   Append(qprefix, ")>");
1706   Append(qprefix, tsuffix);
1707   Delete(parms);
1708   Delete(tprefix);
1709   Delete(tsuffix);
1710   Delete(templateargs);
1711   return qprefix;
1712 }
1713 
1714 
1715 /* -----------------------------------------------------------------------------
1716  * Swig_symbol_typedef_reduce()
1717  *
1718  * Chase a typedef through symbol tables looking for a match.
1719  * ----------------------------------------------------------------------------- */
1720 
Swig_symbol_typedef_reduce(const SwigType * ty,Symtab * tab)1721 SwigType *Swig_symbol_typedef_reduce(const SwigType *ty, Symtab *tab) {
1722   SwigType *prefix, *base;
1723   Node *n;
1724   String *nt;
1725 
1726   base = SwigType_base(ty);
1727   prefix = SwigType_prefix(ty);
1728 
1729   n = Swig_symbol_clookup(base, tab);
1730   if (!n) {
1731     if (SwigType_istemplate(ty)) {
1732       SwigType *qt = Swig_symbol_template_reduce(base, tab);
1733       Append(prefix, qt);
1734       Delete(qt);
1735 #ifdef SWIG_DEBUG
1736       Printf(stderr, "symbol_reduce (a) %s %s\n", ty, prefix);
1737 #endif
1738       Delete(base);
1739       return prefix;
1740     } else {
1741       Delete(prefix);
1742 #ifdef SWIG_DEBUG
1743       Printf(stderr, "symbol_reduce (b) %s %s\n", ty, ty);
1744 #endif
1745       return Copy(ty);
1746     }
1747   }
1748   nt = Getattr(n, "nodeType");
1749   if (Equal(nt, "using")) {
1750     String *uname = Getattr(n, "uname");
1751     if (uname) {
1752       n = Swig_symbol_clookup(base, Getattr(n, "sym:symtab"));
1753       if (!n) {
1754 	Delete(base);
1755 	Delete(prefix);
1756 #ifdef SWIG_DEBUG
1757 	Printf(stderr, "symbol_reduce (c) %s %s\n", ty, ty);
1758 #endif
1759 	return Copy(ty);
1760       }
1761     }
1762   }
1763   if (Equal(nt, "cdecl")) {
1764     String *storage = Getattr(n, "storage");
1765     if (storage && (Equal(storage, "typedef"))) {
1766       SwigType *decl;
1767       SwigType *rt;
1768       SwigType *qt;
1769       Symtab *ntab;
1770       SwigType *nt = Copy(Getattr(n, "type"));
1771 
1772       /* Fix for case 'typedef struct Hello hello;' */
1773       {
1774 	const char *dclass[3] = { "struct ", "union ", "class " };
1775 	int i;
1776 	char *c = Char(nt);
1777 	for (i = 0; i < 3; i++) {
1778 	  if (strstr(c, dclass[i]) == c) {
1779 	    Replace(nt, dclass[i], "", DOH_REPLACE_FIRST);
1780 	  }
1781 	}
1782       }
1783       decl = Getattr(n, "decl");
1784       if (decl) {
1785 	SwigType_push(nt, decl);
1786       }
1787       SwigType_push(nt, prefix);
1788       Delete(base);
1789       Delete(prefix);
1790       ntab = Getattr(n, "sym:symtab");
1791       rt = Swig_symbol_typedef_reduce(nt, ntab);
1792       qt = Swig_symbol_type_qualify(rt, ntab);
1793       if (SwigType_istemplate(qt)) {
1794 	SwigType *qtr = Swig_symbol_template_reduce(qt, ntab);
1795 	Delete(qt);
1796 	qt = qtr;
1797       }
1798       Delete(nt);
1799       Delete(rt);
1800 #ifdef SWIG_DEBUG
1801       Printf(stderr, "symbol_reduce (d) %s %s\n", qt, ty);
1802 #endif
1803       return qt;
1804     }
1805   }
1806   Delete(base);
1807   Delete(prefix);
1808 #ifdef SWIG_DEBUG
1809   Printf(stderr, "symbol_reduce (e) %s %s\n", ty, ty);
1810 #endif
1811   return Copy(ty);
1812 }
1813 
1814 /* -----------------------------------------------------------------------------
1815  * Swig_symbol_string_qualify()
1816  *
1817  * This function takes a string and looks for identifiers.  Identifiers are
1818  * then qualified according to scope rules.  This function is used in a number
1819  * of settings including expression evaluation, scoping of conversion operators,
1820  * and so forth.
1821  * ----------------------------------------------------------------------------- */
1822 
Swig_symbol_string_qualify(String * s,Symtab * st)1823 String *Swig_symbol_string_qualify(String *s, Symtab *st) {
1824   int have_id = 0;
1825   String *id = NewStringEmpty();
1826   String *r = NewStringEmpty();
1827   char *c = Char(s);
1828   int first_char = 1;
1829   while (*c) {
1830     if (isalpha((int) *c) || (*c == '_') || (*c == ':') || (*c == '~' && first_char) || (isdigit((int) *c) && !first_char)) {
1831       Putc(*c, id);
1832       have_id = 1;
1833     } else {
1834       if (have_id) {
1835 	String *qid = Swig_symbol_type_qualify(id, st);
1836 	Append(r, qid);
1837 	Clear(id);
1838 	Delete(qid);
1839 	have_id = 0;
1840       }
1841       Putc(*c, r);
1842     }
1843     first_char = (*c == ':');
1844     c++;
1845   }
1846   if (have_id) {
1847     String *qid = Swig_symbol_type_qualify(id, st);
1848     Append(r, qid);
1849     Delete(qid);
1850   }
1851   Delete(id);
1852   return r;
1853 }
1854 
1855 
1856 /* -----------------------------------------------------------------------------
1857  * Swig_symbol_template_defargs()
1858  *
1859  * Apply default arg from generic template default args
1860  * Returns a parameter list which contains missing default arguments (if any)
1861  * Note side effects: parms will also contain the extra parameters in its list
1862  * (but only if non-zero).
1863  * ----------------------------------------------------------------------------- */
1864 
1865 
Swig_symbol_template_defargs(Parm * parms,Parm * targs,Symtab * tscope,Symtab * tsdecl)1866 ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl) {
1867   ParmList *expandedparms = parms;
1868   if (Len(parms) < Len(targs)) {
1869     Parm *lp = parms;
1870     Parm *p = lp;
1871     Parm *tp = targs;
1872     while (p && tp) {
1873       p = nextSibling(p);
1874       tp = nextSibling(tp);
1875       if (p)
1876 	lp = p;
1877     }
1878     while (tp) {
1879       String *value = Getattr(tp, "value");
1880       if (value) {
1881 	Parm *cp;
1882 	Parm *ta = targs;
1883 	Parm *p = parms;
1884 	SwigType *nt = Swig_symbol_string_qualify(value, tsdecl);
1885 	SwigType *ntq = 0;
1886 #ifdef SWIG_DEBUG
1887 	Printf(stderr, "value %s %s %s\n", value, nt, tsdecl ? Getattr(tsdecl, "name") : tsdecl);
1888 #endif
1889 	while (p && ta) {
1890 	  String *name = Getattr(ta, "name");
1891 	  String *pvalue = Getattr(p, "value");
1892 	  String *value = pvalue ? pvalue : Getattr(p, "type");
1893 	  String *ttq = Swig_symbol_type_qualify(value, tscope);
1894 	  /* value = SwigType_typedef_resolve_all(value); */
1895 	  Replaceid(nt, name, ttq);
1896 	  p = nextSibling(p);
1897 	  ta = nextSibling(ta);
1898 	  Delete(ttq);
1899 	}
1900 	ntq = Swig_symbol_type_qualify(nt, tsdecl);
1901 	if (SwigType_istemplate(ntq)) {
1902 	  String *ty = Swig_symbol_template_deftype(ntq, tscope);
1903 	  Delete(ntq);
1904 	  ntq = ty;
1905 	}
1906 	cp = NewParmWithoutFileLineInfo(ntq, 0);
1907 	if (lp) {
1908 	  set_nextSibling(lp, cp);
1909 	  Delete(cp);
1910 	} else {
1911 	  expandedparms = cp;
1912 	}
1913 	lp = cp;
1914 	tp = nextSibling(tp);
1915 	Delete(nt);
1916 	Delete(ntq);
1917       } else {
1918 	tp = 0;
1919       }
1920     }
1921   }
1922   return expandedparms;
1923 }
1924 
1925 /* -----------------------------------------------------------------------------
1926  * Swig_symbol_template_deftype()
1927  *
1928  * Apply default args to generic template type
1929  * ----------------------------------------------------------------------------- */
1930 
1931 #define SWIG_TEMPLATE_DEFTYPE_CACHE
Swig_symbol_template_deftype(const SwigType * type,Symtab * tscope)1932 SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) {
1933   String *result = NewStringEmpty();
1934   List *elements = SwigType_split(type);
1935   int len = Len(elements);
1936   int i;
1937 #ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
1938   static Hash *s_cache = 0;
1939   Hash *scope_cache;
1940   /* The lookup depends on the current scope and potential namespace qualification.
1941      Looking up x in namespace y is not the same as looking up x::y in outer scope.
1942      -> we use a 2-level hash: first scope and then symbol. */
1943   String *scope_name = tscope
1944       ? Swig_symbol_qualifiedscopename(tscope)
1945       : Swig_symbol_qualifiedscopename(current_symtab);
1946   String *type_name = tscope
1947       ? NewStringf("%s::%s", Getattr(tscope, "name"), type)
1948       : NewStringf("%s::%s", Swig_symbol_getscopename(), type);
1949   if (!scope_name) scope_name = NewString("::");
1950   if (!s_cache) {
1951     s_cache = NewHash();
1952   }
1953   scope_cache = Getattr(s_cache, scope_name);
1954   if (scope_cache) {
1955     String *cres = Getattr(scope_cache, type_name);
1956     if (cres) {
1957       Append(result, cres);
1958 #ifdef SWIG_DEBUG
1959       Printf(stderr, "cached deftype %s(%s) -> %s\n", type, scope_name, result);
1960 #endif
1961       Delete(type_name);
1962       Delete(scope_name);
1963       return result;
1964     }
1965   } else {
1966       scope_cache = NewHash();
1967       Setattr(s_cache, scope_name, scope_cache);
1968       Delete(scope_name);
1969   }
1970 #endif
1971 
1972 #ifdef SWIG_DEBUG
1973   Printf(stderr, "finding deftype %s\n", type);
1974 #endif
1975 
1976   for (i = 0; i < len; i++) {
1977     String *e = Getitem(elements, i);
1978     if (SwigType_isfunction(e)) {
1979       String *s = NewString("f(");
1980       List *parms = SwigType_parmlist(e);
1981       Iterator pi = First(parms);
1982       while (pi.item) {
1983 	String *pf = SwigType_istemplate(e) ? Swig_symbol_template_deftype(pi.item, tscope)
1984 	    : Swig_symbol_type_qualify(pi.item, tscope);
1985 	Append(s, pf);
1986 	pi = Next(pi);
1987 	if (pi.item) {
1988 	  Append(s, ",");
1989 	}
1990 	Delete(pf);
1991       }
1992       Append(s, ").");
1993       Append(result, s);
1994       Delete(s);
1995       Delete(parms);
1996     } else if (SwigType_istemplate(e)) {
1997       String *prefix = SwigType_prefix(e);
1998       String *base = SwigType_base(e);
1999       String *tprefix = SwigType_templateprefix(base);
2000       String *targs = SwigType_templateargs(base);
2001       String *tsuffix = SwigType_templatesuffix(base);
2002       ParmList *tparms = SwigType_function_parms(targs, 0);
2003       Node *tempn = Swig_symbol_clookup_local(tprefix, tscope);
2004       if (!tempn && tsuffix && Len(tsuffix)) {
2005 	tempn = Swig_symbol_clookup(tprefix, 0);
2006       }
2007 #ifdef SWIG_DEBUG
2008       Printf(stderr, "deftype type %s %s %d\n", e, tprefix, (long) tempn);
2009 #endif
2010       if (tempn) {
2011 	ParmList *tnargs = Getattr(tempn, "templateparms");
2012         ParmList *expandedparms;
2013 	Parm *p;
2014 	Symtab *tsdecl = Getattr(tempn, "sym:symtab");
2015 
2016 #ifdef SWIG_DEBUG
2017 	Printf(stderr, "deftype type %s %s %s\n", tprefix, targs, tsuffix);
2018 #endif
2019 	Append(tprefix, "<(");
2020 	expandedparms = Swig_symbol_template_defargs(tparms, tnargs, tscope, tsdecl);
2021 	p = expandedparms;
2022 	tscope = tsdecl;
2023 	while (p) {
2024 	  SwigType *ptype = Getattr(p, "type");
2025 	  SwigType *ttr = ptype ? ptype : Getattr(p, "value");
2026 	  SwigType *ttf = Swig_symbol_type_qualify(ttr, tscope);
2027 	  SwigType *ttq = Swig_symbol_template_param_eval(ttf, tscope);
2028 #ifdef SWIG_DEBUG
2029 	  Printf(stderr, "arg type %s\n", ttq);
2030 #endif
2031 	  if (SwigType_istemplate(ttq)) {
2032 	    SwigType *ttd = Swig_symbol_template_deftype(ttq, tscope);
2033 	    Delete(ttq);
2034 	    ttq = ttd;
2035 #ifdef SWIG_DEBUG
2036 	    Printf(stderr, "arg deftype %s\n", ttq);
2037 #endif
2038 	  }
2039 	  Append(tprefix, ttq);
2040 	  p = nextSibling(p);
2041 	  if (p)
2042 	    Putc(',', tprefix);
2043 	  Delete(ttf);
2044 	  Delete(ttq);
2045 	}
2046 	Append(tprefix, ")>");
2047 	Append(tprefix, tsuffix);
2048 	Append(prefix, tprefix);
2049 #ifdef SWIG_DEBUG
2050 	Printf(stderr, "deftype %s %s \n", type, tprefix);
2051 #endif
2052 	Append(result, prefix);
2053       } else {
2054 	Append(result, e);
2055       }
2056       Delete(prefix);
2057       Delete(base);
2058       Delete(tprefix);
2059       Delete(tsuffix);
2060       Delete(targs);
2061       Delete(tparms);
2062     } else {
2063       Append(result, e);
2064     }
2065   }
2066   Delete(elements);
2067 #ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
2068   Setattr(scope_cache, type_name, result);
2069   Delete(type_name);
2070 #endif
2071 
2072   return result;
2073 }
2074 
Swig_symbol_template_param_eval(const SwigType * p,Symtab * symtab)2075 SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab) {
2076   String *value = Copy(p);
2077   Node *lastnode = 0;
2078   while (1) {
2079     Node *n = Swig_symbol_clookup(value, symtab);
2080     if (n == lastnode)
2081       break;
2082     lastnode = n;
2083     if (n) {
2084       String *nt = Getattr(n, "nodeType");
2085       if (Equal(nt, "enumitem")) {
2086 	/* An enum item.   Generate a fully qualified name */
2087 	String *qn = Swig_symbol_qualified(n);
2088 	if (qn && Len(qn)) {
2089 	  Append(qn, "::");
2090 	  Append(qn, Getattr(n, "name"));
2091 	  Delete(value);
2092 	  value = qn;
2093 	  continue;
2094 	} else {
2095 	  Delete(qn);
2096 	  break;
2097 	}
2098       } else if ((Equal(nt, "cdecl"))) {
2099 	String *nv = Getattr(n, "value");
2100 	if (nv) {
2101 	  Delete(value);
2102 	  value = Copy(nv);
2103 	  continue;
2104 	}
2105       }
2106     }
2107     break;
2108   }
2109   return value;
2110 }
2111