1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * This module builds all of the internal type information by collecting
8 * typedef declarations as well as registering classes, structures, and unions.
9 * This information is needed to correctly handle shadow classes and other
10 * advanced features. This phase of compilation is also used to perform
11 * type-expansion. All types are fully qualified with namespace prefixes
12 * and other information needed for compilation.
13 * ----------------------------------------------------------------------------- */
15 char cvsroot_typepass_cxx[] = "$Id: typepass.cxx 11279 2009-06-16 19:29:08Z wsfulton $";
27 static normal_node *patch_list = 0;
29 /* Singleton class - all non-static methods in this class are private */
30 class TypePass:private Dispatcher {
41 /* Normalize a type. Replaces type with fully qualified version */
42 void normalize_type(SwigType *ty) {
45 Replaceall(ty, "struct ", "");
46 Replaceall(ty, "union ", "");
47 Replaceall(ty, "class ", "");
50 qty = SwigType_typedef_qualified(ty);
51 /* Printf(stdout,"%s --> %s\n", ty, qty); */
57 /* Normalize a parameter list */
59 void normalize_parms(ParmList *p) {
61 SwigType *ty = Getattr(p, "type");
63 /* This is a check for a function type */
65 SwigType *qty = SwigType_typedef_resolve_all(ty);
66 if (SwigType_isfunction(qty)) {
67 SwigType_add_pointer(ty);
72 String *value = Getattr(p, "value");
74 Node *n = Swig_symbol_clookup(value, 0);
76 String *q = Swig_symbol_qualified(n);
78 String *vb = Swig_scopename_last(value);
80 Printf(value, "%s::%s", SwigType_namestr(q), vb);
85 if (value && SwigType_istemplate(value)) {
86 String *nv = SwigType_namestr(value);
87 Setattr(p, "value", nv);
93 void normalize_later(ParmList *p) {
95 SwigType *ty = Getattr(p, "type");
96 Append(normalize, ty);
101 /* Walk through entries in normalize list and patch them up */
102 void normalize_list() {
103 Hash *currentsym = Swig_symbol_current();
105 normal_node *nn = patch_list;
108 Swig_symbol_setscope(nn->symtab);
109 SwigType_set_scope(nn->typescope);
111 for (t = First(nn->normallist); t.item; t = Next(t)) {
112 normalize_type(t.item);
114 Delete(nn->normallist);
119 Swig_symbol_setscope(currentsym);
122 /* generate C++ inheritance type-relationships */
123 void cplus_inherit_types_impl(Node *first, Node *cls, String *clsname, const char *bases, const char *baselist, int ispublic, String *cast = 0) {
126 return; /* The Marcelo check */
130 List *ilist = Getattr(cls, bases);
132 List *nlist = Getattr(cls, baselist);
134 int len = Len(nlist);
136 for (i = 0; i < len; i++) {
139 String *bname = Getitem(nlist, i);
140 String *sname = bname;
143 /* Try to locate the base class. We look in the symbol table and we chase
144 typedef declarations to get to the base class if necessary */
145 Symtab *st = Getattr(cls, "sym:symtab");
147 if (SwigType_istemplate(bname)) {
148 tname = SwigType_typedef_resolve_all(bname);
152 String *qsname = SwigType_typedef_qualified(sname);
153 bcls = Swig_symbol_clookup(qsname, st);
156 if (Strcmp(nodeType(bcls), "class") != 0) {
157 /* Not a class. The symbol could be a typedef. */
158 if (checkAttribute(bcls, "storage", "typedef")) {
159 SwigType *decl = Getattr(bcls, "decl");
160 if (!decl || !(Len(decl))) {
161 sname = Getattr(bcls, "type");
162 st = Getattr(bcls, "sym:symtab");
163 if (SwigType_istemplate(sname)) {
166 tname = SwigType_typedef_resolve_all(sname);
172 if (Strcmp(nodeType(bcls), "classforward") != 0) {
173 Swig_error(Getfile(cls), Getline(cls), "'%s' does not have a valid base class.\n", Getattr(cls, "name"));
174 Swig_error(Getfile(bcls), Getline(bcls), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
176 Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(cls), Getline(cls), "Base class '%s' is incomplete.\n", SwigType_namestr(bname));
177 Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname));
182 if (Getattr(bcls, "typepass:visit")) {
184 ilist = alist = NewList();
187 Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Base class '%s' undefined.\n", SwigType_namestr(bname));
188 Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "'%s' must be defined before it is used as a base class.\n", SwigType_namestr(bname));
199 if (ispublic && !Getmeta(bname, "already_warned")) {
200 Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
201 if (Strchr(bname, '<')) {
202 Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Maybe you forgot to instantiate '%s' using %%template.\n",
203 SwigType_namestr(bname));
205 Setmeta(bname, "already_warned", "1");
208 SwigType_inherit(clsname, bname, cast, 0);
213 Setattr(cls, bases, ilist);
221 int len = Len(ilist);
223 for (i = 0; i < len; i++) {
224 Node *n = Getitem(ilist, i);
225 String *bname = Getattr(n, "name");
226 Node *bclass = n; /* Getattr(n,"class"); */
227 Hash *scopes = Getattr(bclass, "typescope");
228 SwigType_inherit(clsname, bname, cast, 0);
230 String *btype = Copy(bname);
231 SwigType_add_pointer(btype);
232 SwigType_remember(btype);
236 SwigType_inherit_scope(scopes);
238 /* Set up inheritance in the symbol table */
239 Symtab *st = Getattr(cls, "symtab");
240 Symtab *bst = Getattr(bclass, "symtab");
242 Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", Getattr(cls, "name"));
245 Symtab *s = Swig_symbol_current();
246 Swig_symbol_setscope(st);
247 Swig_symbol_inherit(bst);
248 Swig_symbol_setscope(s);
250 /* Recursively hit base classes */
251 String *namestr = SwigType_namestr(Getattr(bclass, "name"));
252 String *newcast = NewStringf("(%s *)%s", namestr, cast);
254 cplus_inherit_types_impl(first, bclass, clsname, bases, baselist, ispublic, newcast);
259 void append_list(List *lb, List *la) {
261 for (Iterator bi = First(la); bi.item; bi = Next(bi)) {
267 void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
268 cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast);
269 cplus_inherit_types_impl(first, cls, clsname, "protectedbases", "protectedbaselist", 0, cast);
270 cplus_inherit_types_impl(first, cls, clsname, "privatebases", "privatebaselist", 0, cast);
275 List *allbases = NewList();
276 append_list(allbases, Getattr(cls, "bases"));
277 append_list(allbases, Getattr(cls, "protectedbases"));
278 append_list(allbases, Getattr(cls, "privatebases"));
280 Setattr(cls, "allbases", allbases);
285 /* ------------------------------------------------------------
287 * ------------------------------------------------------------ */
289 virtual int top(Node *n) {
291 module = Getattr(n, "module");
295 classhash = Getattr(n, "classes");
298 SwigType_set_scope(0);
303 /* ------------------------------------------------------------
305 * ------------------------------------------------------------ */
307 virtual int moduleDirective(Node *n) {
314 /* ------------------------------------------------------------
316 * ------------------------------------------------------------ */
318 virtual int importDirective(Node *n) {
319 String *oldmodule = module;
320 int oldimport = importmode;
324 importmode = oldimport;
329 /* ------------------------------------------------------------
333 * ------------------------------------------------------------ */
335 virtual int includeDirective(Node *n) {
336 return emit_children(n);
338 virtual int externDeclaration(Node *n) {
339 return emit_children(n);
341 virtual int extendDirective(Node *n) {
342 return emit_children(n);
345 /* ------------------------------------------------------------
347 * ------------------------------------------------------------ */
349 virtual int classDeclaration(Node *n) {
350 String *name = Getattr(n, "name");
351 String *tdname = Getattr(n, "tdname");
352 String *unnamed = Getattr(n, "unnamed");
353 String *storage = Getattr(n, "storage");
354 String *kind = Getattr(n, "kind");
355 Node *oldinclass = inclass;
356 List *olist = normalize;
360 String *scopename = 0;
362 normalize = NewList();
365 if (SwigType_istemplate(name)) {
366 // We need to fully resolve the name to make templates work correctly */
368 fname = SwigType_typedef_resolve_all(name);
369 if (Strcmp(fname, name) != 0 && (cn = Swig_symbol_clookup_local(fname, 0))) {
371 || (Strcmp(nodeType(cn), "template") == 0)
372 || (Getattr(cn, "feature:onlychildren") != 0)
373 || (Getattr(n, "feature:onlychildren") != 0)) {
374 Swig_symbol_cadd(fname, n);
375 SwigType_typedef_class(fname);
376 scopename = Copy(fname);
378 Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
379 Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
383 Swig_symbol_cadd(fname, n);
384 SwigType_typedef_class(fname);
385 scopename = Copy(fname);
388 if ((CPlusPlus) || (unnamed)) {
389 SwigType_typedef_class(name);
391 SwigType_typedef_class(NewStringf("%s %s", kind, name));
393 scopename = Copy(name);
399 Setattr(n, "typepass:visit", "1");
401 /* Need to set up a typedef if unnamed */
402 if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
403 SwigType_typedef(unnamed, tdname);
407 nname = NewStringf("%s::%s", nsname, name);
408 String *tdname = Getattr(n, "tdname");
410 tdname = NewStringf("%s::%s", nsname, tdname);
411 Setattr(n, "tdname", tdname);
414 SwigType_new_scope(scopename);
415 SwigType_attach_symtab(Getattr(n, "symtab"));
417 /* Inherit type definitions into the class */
419 cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
423 symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
425 Swig_symbol_setscope(symtab);
427 Hash *ts = SwigType_pop_scope();
428 Setattr(n, "typescope", ts);
430 Setattr(n, "module", module);
432 /* Normalize deferred types */
434 normal_node *nn = new normal_node();
435 nn->normallist = normalize;
436 nn->symtab = Getattr(n, "symtab");
437 nn->next = patch_list;
438 nn->typescope = Getattr(n, "typescope");
444 inclass = oldinclass;
446 /* If in a namespace, patch the class name */
448 Setattr(n, "name", nname);
454 /* ------------------------------------------------------------
455 * namespaceDeclaration()
456 * ------------------------------------------------------------ */
458 virtual int templateDeclaration(Node *n) {
459 String *name = Getattr(n, "name");
460 String *ttype = Getattr(n, "templatetype");
461 if (Strcmp(ttype, "class") == 0) {
462 String *rname = SwigType_typedef_resolve_all(name);
463 SwigType_typedef_class(rname);
465 } else if (Strcmp(ttype, "classforward") == 0) {
466 String *rname = SwigType_typedef_resolve_all(name);
467 SwigType_typedef_class(rname);
469 /* SwigType_typedef_class(name); */
474 /* ------------------------------------------------------------
475 * classforwardDeclaration()
476 * ------------------------------------------------------------ */
478 virtual int classforwardDeclaration(Node *n) {
480 /* Temporary hack. Can't do inside a class because it breaks
481 C nested structure wrapping */
483 if ((!inclass) || (CPlusPlus)) {
484 String *name = Getattr(n, "name");
486 SwigType_typedef_class(name);
488 nname = NewStringf("%s::%s", nsname, name);
489 Setattr(n, "name", nname);
496 /* ------------------------------------------------------------
497 * namespaceDeclaration()
498 * ------------------------------------------------------------ */
500 virtual int namespaceDeclaration(Node *n) {
502 String *name = Getattr(n, "name");
503 String *alias = Getattr(n, "alias");
504 List *olist = normalize;
505 normalize = NewList();
507 Typetab *ts = Getattr(n, "typescope");
510 /* Create a empty scope for the alias */
511 ns = Getattr(n, "namespace");
513 SwigType_scope_alias(name, Getattr(ns, "typescope"));
515 ts = Getattr(ns, "typescope");
516 Setattr(n, "typescope", ts);
518 /* Namespace alias */
522 Node *nn = Swig_symbol_clookup(name, n);
525 ts = Getattr(nn, "typescope");
527 SwigType_new_scope(name);
528 SwigType_attach_symtab(Getattr(n, "symtab"));
530 SwigType_set_scope(ts);
533 String *oldnsname = nsname;
534 nsname = Swig_symbol_qualified(Getattr(n, "symtab"));
535 symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
537 Swig_symbol_setscope(symtab);
540 Hash *ts = SwigType_pop_scope();
541 Setattr(n, "typescope", ts);
545 /* Normalize deferred types */
547 normal_node *nn = new normal_node();
548 nn->normallist = normalize;
549 nn->symtab = Getattr(n, "symtab");
550 nn->next = patch_list;
551 nn->typescope = Getattr(n, "typescope");
562 /* ------------------------------------------------------------
564 * ------------------------------------------------------------ */
566 virtual int cDeclaration(Node *n) {
568 Delattr(n, "throws");
571 /* Normalize types. */
572 SwigType *ty = Getattr(n, "type");
574 SwigType *decl = Getattr(n, "decl");
576 normalize_type(decl);
578 normalize_parms(Getattr(n, "parms"));
579 normalize_parms(Getattr(n, "throws"));
580 if (GetFlag(n, "conversion_operator")) {
581 /* The call to the operator in the generated wrapper must be fully qualified in order to compile */
582 SwigType *name = Getattr(n, "name");
583 SwigType *qualifiedname = Swig_symbol_string_qualify(name,0);
585 Append(name, qualifiedname);
586 Delete(qualifiedname);
589 if (checkAttribute(n, "storage", "typedef")) {
590 String *name = Getattr(n, "name");
591 ty = Getattr(n, "type");
592 decl = Getattr(n, "decl");
593 SwigType *t = Copy(ty);
595 /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */
596 if (Swig_scopename_check(t) && strncmp(Char(t), "::", 2)) {
597 String *base, *prefix, *qprefix;
598 base = Swig_scopename_last(t);
599 prefix = Swig_scopename_prefix(t);
600 qprefix = SwigType_typedef_qualified(prefix);
602 t = NewStringf("%s::%s", qprefix, base);
608 SwigType_push(t, decl);
610 Replaceall(t, "struct ", "");
611 Replaceall(t, "union ", "");
612 Replaceall(t, "class ", "");
614 SwigType_typedef(t, name);
616 /* If namespaces are active. We need to patch the name with a namespace prefix */
617 if (nsname && !inclass) {
618 String *name = Getattr(n, "name");
620 String *nname = NewStringf("%s::%s", nsname, name);
621 Setattr(n, "name", nname);
630 /* ------------------------------------------------------------
631 * constructorDeclaration()
632 * ------------------------------------------------------------ */
634 virtual int constructorDeclaration(Node *n) {
636 Delattr(n, "throws");
639 normalize_parms(Getattr(n, "parms"));
640 normalize_parms(Getattr(n, "throws"));
642 /* If in a namespace, patch the class name */
644 String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
645 Setattr(n, "name", nname);
651 /* ------------------------------------------------------------
652 * destructorDeclaration()
653 * ------------------------------------------------------------ */
655 virtual int destructorDeclaration(Node *n) {
656 /* If in a namespace, patch the class name */
658 String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
659 Setattr(n, "name", nname);
664 /* ------------------------------------------------------------
665 * constantDirective()
666 * ------------------------------------------------------------ */
668 virtual int constantDirective(Node *n) {
669 SwigType *ty = Getattr(n, "type");
671 Setattr(n, "type", SwigType_typedef_qualified(ty));
677 /* ------------------------------------------------------------
679 * ------------------------------------------------------------ */
681 virtual int enumDeclaration(Node *n) {
682 String *name = Getattr(n, "name");
687 // Add a typedef to the type table so that we can use 'enum Name' as well as just 'Name'
688 if (nsname || inclass) {
690 // But first correct the name and tdname to contain the fully qualified scopename
691 if (nsname && inclass) {
692 scope = NewStringf("%s::%s", nsname, Getattr(inclass, "name"));
694 scope = NewStringf("%s", nsname);
695 } else if (inclass) {
696 scope = NewStringf("%s", Getattr(inclass, "name"));
699 String *nname = NewStringf("%s::%s", scope, name);
700 Setattr(n, "name", nname);
702 String *tdname = Getattr(n, "tdname");
704 tdname = NewStringf("%s::%s", scope, tdname);
705 Setattr(n, "tdname", tdname);
708 SwigType *t = NewStringf("enum %s", nname);
709 SwigType_typedef(t, name);
711 SwigType *t = NewStringf("enum %s", name);
712 SwigType_typedef(t, name);
717 String *tdname = Getattr(n, "tdname");
718 String *unnamed = Getattr(n, "unnamed");
719 String *storage = Getattr(n, "storage");
721 // Construct enumtype - for declaring an enum of this type with SwigType_ltype() etc
722 String *enumtype = 0;
723 if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
724 enumtype = Copy(Getattr(n, "tdname"));
726 enumtype = NewStringf("%s%s", CPlusPlus ? "" : "enum ", Getattr(n, "name"));
729 enumtype = Copy(Getattr(n, "type"));
731 Setattr(n, "enumtype", enumtype);
733 // This block of code is for dealing with %ignore on an enum item where the target language
734 // attempts to use the C enum value in the target language itself and expects the previous enum value
735 // to be one more than the previous value... the previous enum item might not exist if it is ignored!
736 // - It sets the first non-ignored enum item with the "firstenumitem" attribute.
737 // - It adds an enumvalue attribute if the previous enum item is ignored
741 String *previous = 0;
742 bool previous_ignored = false;
743 bool firstenumitem = false;
744 for (c = firstChild(n); c; c = nextSibling(c)) {
745 assert(strcmp(Char(nodeType(c)), "enumitem") == 0);
748 String *enumvalue = Getattr(c, "enumvalue");
749 if (GetFlag(c, "feature:ignore")) {
750 reset = enumvalue ? true : false;
751 previous_ignored = true;
753 if (!enumvalue && previous_ignored) {
755 Setattr(c, "enumvalue", NewStringf("(%s) + %d", previous, count+1));
757 Setattr(c, "enumvalue", NewStringf("%d", count));
758 SetFlag(c, "virtenumvalue"); // identify enumvalue as virtual, ie not from the parsed source
760 if (!firstenumitem) {
761 SetFlag(c, "firstenumitem");
762 firstenumitem = true;
765 previous_ignored = false;
768 previous = enumvalue ? enumvalue : Getattr(c, "name");
780 /* ------------------------------------------------------------
781 * enumvalueDeclaration()
782 * ------------------------------------------------------------ */
784 virtual int enumvalueDeclaration(Node *n) {
785 String *name = Getattr(n, "name");
786 String *value = Getattr(n, "value");
789 if (Strcmp(value, name) == 0) {
791 if (((nsname) || (inclass)) && cparse_cplusplus) {
792 new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
794 new_value = NewString(value);
796 Setattr(n, "value", new_value);
799 Node *next = nextSibling(n);
801 // Make up an enumvalue if one was not specified in the parsed code (not designed to be used on enum items and %ignore - enumvalue will be set instead)
802 if (!GetFlag(n, "feature:ignore")) {
803 if (Getattr(n, "_last") && !Getattr(n, "enumvalue")) { // Only the first enum item has _last set (Note: first non-ignored enum item has firstenumitem set)
804 Setattr(n, "enumvalueex", "0");
806 if (next && !Getattr(next, "enumvalue")) {
807 Setattr(next, "enumvalueex", NewStringf("%s + 1", Getattr(n, "sym:name")));
814 /* ------------------------------------------------------------
815 * enumforwardDeclaration()
816 * ------------------------------------------------------------ */
818 virtual int enumforwardDeclaration(Node *n) {
820 // Use enumDeclaration() to do all the hard work.
821 // Note that no children can be emitted in a forward declaration as there aren't any.
822 return enumDeclaration(n);
825 #ifdef DEBUG_OVERLOADED
826 static void show_overloaded(Node *n) {
827 Node *c = Getattr(n, "sym:overloaded");
828 Node *checkoverloaded = c;
829 Printf(stdout, "-------------------- overloaded start %s sym:overloaded():%p -------------------------------\n", Getattr(n, "name"), c);
831 if (Getattr(c, "error")) {
832 c = Getattr(c, "sym:nextSibling");
835 if (Getattr(c, "sym:overloaded") != checkoverloaded) {
836 Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
841 String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
842 Printf(stdout, " show_overloaded %s::%s(%s) [%s] nodeType:%s\n", parentNode(c) ? Getattr(parentNode(c), "name") : "NOPARENT", Getattr(c, "name"), decl, Getattr(c, "sym:overname"), nodeType(c));
843 if (!Getattr(c, "sym:overloaded")) {
844 Printf(stdout, "sym:overloaded error.....%p\n", c);
848 c = Getattr(c, "sym:nextSibling");
850 Printf(stdout, "-------------------- overloaded end %s -------------------------------\n", Getattr(n, "name"));
854 /* ------------------------------------------------------------
856 * ------------------------------------------------------------ */
858 virtual int usingDeclaration(Node *n) {
859 if (Getattr(n, "namespace")) {
860 /* using namespace id */
862 /* For a namespace import. We set up inheritance in the type system */
863 Node *ns = Getattr(n, "node");
865 Typetab *ts = Getattr(ns, "typescope");
867 SwigType_using_scope(ts);
874 Symtab *stab = Getattr(n, "sym:symtab");
876 String *uname = Getattr(n, "uname");
877 ns = Swig_symbol_clookup(uname, stab);
878 if (!ns && SwigType_istemplate(uname)) {
879 String *tmp = Swig_symbol_template_deftype(uname, 0);
880 if (!Equal(tmp, uname)) {
881 ns = Swig_symbol_clookup(tmp, stab);
890 Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname")));
893 /* Only a single symbol is being used. There are only a few symbols that
894 we actually care about. These are typedef, class declarations, and enum */
895 String *ntype = nodeType(ns);
896 if (Strcmp(ntype, "cdecl") == 0) {
897 if (checkAttribute(ns, "storage", "typedef")) {
898 /* A typedef declaration */
899 String *uname = Getattr(n, "uname");
900 SwigType_typedef_using(uname);
902 /* A normal C declaration. */
903 if ((inclass) && (!GetFlag(n, "feature:ignore")) && (Getattr(n, "sym:name"))) {
905 Node *unodes = 0, *last_unodes = 0;
907 String *symname = Getattr(n, "sym:name");
909 if (Strcmp(nodeType(c), "cdecl") == 0) {
910 if (!(checkAttribute(c, "storage", "static")
911 || checkAttribute(c, "storage", "typedef")
912 || checkAttribute(c, "storage", "friend")
913 || (Getattr(c, "feature:extend") && !Getattr(c, "code"))
914 || GetFlag(c, "feature:ignore"))) {
916 /* Don't generate a method if the method is overridden in this class,
917 * for example don't generate another m(bool) should there be a Base::m(bool) :
918 * struct Derived : Base {
923 String *csymname = Getattr(c, "sym:name");
924 if (!csymname || (Strcmp(csymname, symname) == 0)) {
926 String *decl = Getattr(c, "decl");
927 Node *over = Getattr(n, "sym:overloaded");
930 String *odecl = Getattr(over, "decl");
931 if (Cmp(decl, odecl) == 0) {
935 over = Getattr(over, "sym:nextSibling");
938 c = Getattr(c, "csym:nextSibling");
942 Node *nn = copyNode(c);
943 Delattr(nn, "access"); // access might be different from the method in the base class
944 if (!Getattr(nn, "sym:name"))
945 Setattr(nn, "sym:name", symname);
947 if (!GetFlag(nn, "feature:ignore")) {
948 ParmList *parms = CopyParmList(Getattr(c, "parms"));
949 int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
950 int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
951 Setattr(nn, "parms", parms);
953 if (Getattr(n, "feature:extend")) {
954 String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
956 for (ParmList *p = parms; p;) {
957 Append(ucode, Getattr(p, "name"));
962 Append(ucode, "); }");
963 Setattr(nn, "code", ucode);
966 ParmList *throw_parm_list = Getattr(c, "throws");
968 Setattr(nn, "throws", CopyParmList(throw_parm_list));
974 Setattr(nn, "previousSibling", last_unodes);
975 Setattr(last_unodes, "nextSibling", nn);
976 Setattr(nn, "sym:previousSibling", last_unodes);
977 Setattr(last_unodes, "sym:nextSibling", nn);
978 Setattr(nn, "sym:overloaded", unodes);
979 Setattr(unodes, "sym:overloaded", unodes);
988 c = Getattr(c, "csym:nextSibling");
991 set_firstChild(n, unodes);
993 if (!Getattr(n, "sym:overloaded")) {
994 Setattr(n, "sym:overloaded", n);
995 Setattr(n, "sym:overname", "_SWIG_0");
1000 /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
1001 * list of overloaded methods we have just added in as child nodes to the "using" node.
1002 * The node will still exist, it is just the symbol table linked list of overloaded methods
1003 * which is hacked. */
1004 if (Getattr(n, "sym:overloaded"))
1006 #ifdef DEBUG_OVERLOADED
1010 Node *debugnode = n;
1011 if (!firstChild(n)) {
1012 // Remove from overloaded list ('using' node does not actually end up adding in any methods)
1013 Node *ps = Getattr(n, "sym:previousSibling");
1014 Node *ns = Getattr(n, "sym:nextSibling");
1016 Setattr(ps, "sym:nextSibling", ns);
1019 Setattr(ns, "sym:previousSibling", ps);
1022 // The 'using' node results in methods being added in - slot in the these methods here
1023 Node *ps = Getattr(n, "sym:previousSibling");
1024 Node *ns = Getattr(n, "sym:nextSibling");
1025 Node *fc = firstChild(n);
1028 Node *firstoverloaded = Getattr(n, "sym:overloaded");
1029 if (firstoverloaded == n) {
1030 // This 'using' node we are cutting out was the first node in the overloaded list.
1031 // Change the first node in the list to its first sibling
1032 Delattr(firstoverloaded, "sym:overloaded");
1033 Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
1034 firstoverloaded = fc;
1036 Setattr(nnn, "sym:overloaded", firstoverloaded);
1037 nnn = Getattr(nnn, "sym:nextSibling");
1041 Node *ppn = Getattr(pp, "sym:nextSibling");
1042 Setattr(pp, "sym:overloaded", firstoverloaded);
1043 Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
1050 Setattr(ps, "sym:nextSibling", fc);
1051 Setattr(fc, "sym:previousSibling", ps);
1054 Setattr(ns, "sym:previousSibling", pp);
1055 Setattr(pp, "sym:nextSibling", ns);
1057 debugnode = firstoverloaded;
1059 Delattr(n, "sym:previousSibling");
1060 Delattr(n, "sym:nextSibling");
1061 Delattr(n, "sym:overloaded");
1062 Delattr(n, "sym:overname");
1063 #ifdef DEBUG_OVERLOADED
1064 show_overloaded(debugnode);
1066 clean_overloaded(n); // Needed?
1070 } else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
1071 /* We install the using class name as kind of a typedef back to the original class */
1072 String *uname = Getattr(n, "uname");
1073 /* Import into current type scope */
1074 SwigType_typedef_using(uname);
1075 } else if (Strcmp(ntype, "enum") == 0) {
1076 SwigType_typedef_using(Getattr(n, "uname"));
1083 /* ------------------------------------------------------------
1084 * typemapDirective()
1085 * ------------------------------------------------------------ */
1087 virtual int typemapDirective(Node *n) {
1088 if (inclass || nsname) {
1089 Node *items = firstChild(n);
1091 Parm *pattern = Getattr(items, "pattern");
1092 Parm *parms = Getattr(items, "parms");
1093 normalize_later(pattern);
1094 normalize_later(parms);
1095 items = nextSibling(items);
1102 /* ------------------------------------------------------------
1103 * typemapcopyDirective()
1104 * ------------------------------------------------------------ */
1106 virtual int typemapcopyDirective(Node *n) {
1107 if (inclass || nsname) {
1108 Node *items = firstChild(n);
1109 ParmList *pattern = Getattr(n, "pattern");
1110 normalize_later(pattern);
1112 ParmList *npattern = Getattr(items, "pattern");
1113 normalize_later(npattern);
1114 items = nextSibling(items);
1120 /* ------------------------------------------------------------
1122 * ------------------------------------------------------------ */
1124 virtual int applyDirective(Node *n) {
1125 if (inclass || nsname) {
1126 ParmList *pattern = Getattr(n, "pattern");
1127 normalize_later(pattern);
1128 Node *items = firstChild(n);
1130 Parm *apattern = Getattr(items, "pattern");
1131 normalize_later(apattern);
1132 items = nextSibling(items);
1138 /* ------------------------------------------------------------
1140 * ------------------------------------------------------------ */
1142 virtual int clearDirective(Node *n) {
1143 if (inclass || nsname) {
1145 for (p = firstChild(n); p; p = nextSibling(p)) {
1146 ParmList *pattern = Getattr(p, "pattern");
1147 normalize_later(pattern);
1154 static void pass(Node *n) {
1160 void Swig_process_types(Node *n) {