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