summaryrefslogtreecommitdiff
path: root/Source/Modules/typepass.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/typepass.cxx')
-rw-r--r--Source/Modules/typepass.cxx1164
1 files changed, 1164 insertions, 0 deletions
diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx
new file mode 100644
index 0000000..6cb7f0a
--- /dev/null
+++ b/Source/Modules/typepass.cxx
@@ -0,0 +1,1164 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * typepass.cxx
+ *
+ * This module builds all of the internal type information by collecting
+ * typedef declarations as well as registering classes, structures, and unions.
+ * This information is needed to correctly handle shadow classes and other
+ * advanced features. This phase of compilation is also used to perform
+ * type-expansion. All types are fully qualified with namespace prefixes
+ * and other information needed for compilation.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_typepass_cxx[] = "$Id: typepass.cxx 11279 2009-06-16 19:29:08Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+
+struct normal_node {
+ Symtab *symtab;
+ Hash *typescope;
+ List *normallist;
+ normal_node *next;
+};
+
+static normal_node *patch_list = 0;
+
+/* Singleton class - all non-static methods in this class are private */
+class TypePass:private Dispatcher {
+ Node *inclass;
+ Node *module;
+ int importmode;
+ String *nsname;
+ Hash *classhash;
+ List *normalize;
+
+ TypePass() {
+ }
+
+ /* Normalize a type. Replaces type with fully qualified version */
+ void normalize_type(SwigType *ty) {
+ SwigType *qty;
+ if (CPlusPlus) {
+ Replaceall(ty, "struct ", "");
+ Replaceall(ty, "union ", "");
+ Replaceall(ty, "class ", "");
+ }
+
+ qty = SwigType_typedef_qualified(ty);
+ /* Printf(stdout,"%s --> %s\n", ty, qty); */
+ Clear(ty);
+ Append(ty, qty);
+ Delete(qty);
+ }
+
+ /* Normalize a parameter list */
+
+ void normalize_parms(ParmList *p) {
+ while (p) {
+ SwigType *ty = Getattr(p, "type");
+ normalize_type(ty);
+ /* This is a check for a function type */
+ {
+ SwigType *qty = SwigType_typedef_resolve_all(ty);
+ if (SwigType_isfunction(qty)) {
+ SwigType_add_pointer(ty);
+ }
+ Delete(qty);
+ }
+
+ String *value = Getattr(p, "value");
+ if (value) {
+ Node *n = Swig_symbol_clookup(value, 0);
+ if (n) {
+ String *q = Swig_symbol_qualified(n);
+ if (q && Len(q)) {
+ String *vb = Swig_scopename_last(value);
+ Clear(value);
+ Printf(value, "%s::%s", SwigType_namestr(q), vb);
+ Delete(q);
+ }
+ }
+ }
+ if (value && SwigType_istemplate(value)) {
+ String *nv = SwigType_namestr(value);
+ Setattr(p, "value", nv);
+ }
+ p = nextSibling(p);
+ }
+ }
+
+ void normalize_later(ParmList *p) {
+ while (p) {
+ SwigType *ty = Getattr(p, "type");
+ Append(normalize, ty);
+ p = nextSibling(p);
+ }
+ }
+
+ /* Walk through entries in normalize list and patch them up */
+ void normalize_list() {
+ Hash *currentsym = Swig_symbol_current();
+
+ normal_node *nn = patch_list;
+ normal_node *np;
+ while (nn) {
+ Swig_symbol_setscope(nn->symtab);
+ SwigType_set_scope(nn->typescope);
+ Iterator t;
+ for (t = First(nn->normallist); t.item; t = Next(t)) {
+ normalize_type(t.item);
+ }
+ Delete(nn->normallist);
+ np = nn->next;
+ delete(nn);
+ nn = np;
+ }
+ Swig_symbol_setscope(currentsym);
+ }
+
+ /* generate C++ inheritance type-relationships */
+ void cplus_inherit_types_impl(Node *first, Node *cls, String *clsname, const char *bases, const char *baselist, int ispublic, String *cast = 0) {
+
+ if (first == cls)
+ return; /* The Marcelo check */
+ if (!cls)
+ cls = first;
+ List *alist = 0;
+ List *ilist = Getattr(cls, bases);
+ if (!ilist) {
+ List *nlist = Getattr(cls, baselist);
+ if (nlist) {
+ int len = Len(nlist);
+ int i;
+ for (i = 0; i < len; i++) {
+ Node *bcls = 0;
+ int clsforward = 0;
+ String *bname = Getitem(nlist, i);
+ String *sname = bname;
+ String *tname = 0;
+
+ /* Try to locate the base class. We look in the symbol table and we chase
+ typedef declarations to get to the base class if necessary */
+ Symtab *st = Getattr(cls, "sym:symtab");
+
+ if (SwigType_istemplate(bname)) {
+ tname = SwigType_typedef_resolve_all(bname);
+ sname = tname;
+ }
+ while (1) {
+ String *qsname = SwigType_typedef_qualified(sname);
+ bcls = Swig_symbol_clookup(qsname, st);
+ Delete(qsname);
+ if (bcls) {
+ if (Strcmp(nodeType(bcls), "class") != 0) {
+ /* Not a class. The symbol could be a typedef. */
+ if (checkAttribute(bcls, "storage", "typedef")) {
+ SwigType *decl = Getattr(bcls, "decl");
+ if (!decl || !(Len(decl))) {
+ sname = Getattr(bcls, "type");
+ st = Getattr(bcls, "sym:symtab");
+ if (SwigType_istemplate(sname)) {
+ if (tname)
+ Delete(tname);
+ tname = SwigType_typedef_resolve_all(sname);
+ sname = tname;
+ }
+ continue;
+ }
+ }
+ if (Strcmp(nodeType(bcls), "classforward") != 0) {
+ Swig_error(Getfile(cls), Getline(cls), "'%s' does not have a valid base class.\n", Getattr(cls, "name"));
+ Swig_error(Getfile(bcls), Getline(bcls), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
+ } else {
+ Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(cls), Getline(cls), "Base class '%s' is incomplete.\n", SwigType_namestr(bname));
+ Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname));
+ clsforward = 1;
+ }
+ bcls = 0;
+ } else {
+ if (Getattr(bcls, "typepass:visit")) {
+ if (!ilist)
+ ilist = alist = NewList();
+ Append(ilist, bcls);
+ } else {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Base class '%s' undefined.\n", SwigType_namestr(bname));
+ 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));
+ }
+ }
+ }
+ break;
+ }
+
+ if (tname)
+ Delete(tname);
+ if (!bcls) {
+ if (!clsforward) {
+ if (ispublic && !Getmeta(bname, "already_warned")) {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
+ if (Strchr(bname, '<')) {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Maybe you forgot to instantiate '%s' using %%template.\n",
+ SwigType_namestr(bname));
+ }
+ Setmeta(bname, "already_warned", "1");
+ }
+ }
+ SwigType_inherit(clsname, bname, cast, 0);
+ }
+ }
+ }
+ if (ilist) {
+ Setattr(cls, bases, ilist);
+ }
+ }
+ if (alist)
+ Delete(alist);
+
+ if (!ilist)
+ return;
+ int len = Len(ilist);
+ int i;
+ for (i = 0; i < len; i++) {
+ Node *n = Getitem(ilist, i);
+ String *bname = Getattr(n, "name");
+ Node *bclass = n; /* Getattr(n,"class"); */
+ Hash *scopes = Getattr(bclass, "typescope");
+ SwigType_inherit(clsname, bname, cast, 0);
+ if (!importmode) {
+ String *btype = Copy(bname);
+ SwigType_add_pointer(btype);
+ SwigType_remember(btype);
+ Delete(btype);
+ }
+ if (scopes) {
+ SwigType_inherit_scope(scopes);
+ }
+ /* Set up inheritance in the symbol table */
+ Symtab *st = Getattr(cls, "symtab");
+ Symtab *bst = Getattr(bclass, "symtab");
+ if (st == bst) {
+ Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", Getattr(cls, "name"));
+ continue;
+ }
+ Symtab *s = Swig_symbol_current();
+ Swig_symbol_setscope(st);
+ Swig_symbol_inherit(bst);
+ Swig_symbol_setscope(s);
+
+ /* Recursively hit base classes */
+ String *namestr = SwigType_namestr(Getattr(bclass, "name"));
+ String *newcast = NewStringf("(%s *)%s", namestr, cast);
+ Delete(namestr);
+ cplus_inherit_types_impl(first, bclass, clsname, bases, baselist, ispublic, newcast);
+ Delete(newcast);
+ }
+ }
+
+ void append_list(List *lb, List *la) {
+ if (la && lb) {
+ for (Iterator bi = First(la); bi.item; bi = Next(bi)) {
+ Append(lb, bi.item);
+ }
+ }
+ }
+
+ void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
+ cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast);
+ cplus_inherit_types_impl(first, cls, clsname, "protectedbases", "protectedbaselist", 0, cast);
+ cplus_inherit_types_impl(first, cls, clsname, "privatebases", "privatebaselist", 0, cast);
+
+ if (!cls)
+ cls = first;
+
+ List *allbases = NewList();
+ append_list(allbases, Getattr(cls, "bases"));
+ append_list(allbases, Getattr(cls, "protectedbases"));
+ append_list(allbases, Getattr(cls, "privatebases"));
+ if (Len(allbases)) {
+ Setattr(cls, "allbases", allbases);
+ }
+ Delete(allbases);
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+ importmode = 0;
+ module = Getattr(n, "module");
+ inclass = 0;
+ normalize = 0;
+ nsname = 0;
+ classhash = Getattr(n, "classes");
+ emit_children(n);
+ normalize_list();
+ SwigType_set_scope(0);
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * moduleDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int moduleDirective(Node *n) {
+ if (!module) {
+ module = n;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ String *oldmodule = module;
+ int oldimport = importmode;
+ importmode = 1;
+ module = 0;
+ emit_children(n);
+ importmode = oldimport;
+ module = oldmodule;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * includeDirective()
+ * externDirective()
+ * extendDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int includeDirective(Node *n) {
+ return emit_children(n);
+ }
+ virtual int externDeclaration(Node *n) {
+ return emit_children(n);
+ }
+ virtual int extendDirective(Node *n) {
+ return emit_children(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+ String *tdname = Getattr(n, "tdname");
+ String *unnamed = Getattr(n, "unnamed");
+ String *storage = Getattr(n, "storage");
+ String *kind = Getattr(n, "kind");
+ Node *oldinclass = inclass;
+ List *olist = normalize;
+ Symtab *symtab;
+ String *nname = 0;
+ String *fname = 0;
+ String *scopename = 0;
+
+ normalize = NewList();
+
+ if (name) {
+ if (SwigType_istemplate(name)) {
+ // We need to fully resolve the name to make templates work correctly */
+ Node *cn;
+ fname = SwigType_typedef_resolve_all(name);
+ if (Strcmp(fname, name) != 0 && (cn = Swig_symbol_clookup_local(fname, 0))) {
+ if ((n == cn)
+ || (Strcmp(nodeType(cn), "template") == 0)
+ || (Getattr(cn, "feature:onlychildren") != 0)
+ || (Getattr(n, "feature:onlychildren") != 0)) {
+ Swig_symbol_cadd(fname, n);
+ SwigType_typedef_class(fname);
+ scopename = Copy(fname);
+ } else {
+ Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
+ Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
+ scopename = 0;
+ }
+ } else {
+ Swig_symbol_cadd(fname, n);
+ SwigType_typedef_class(fname);
+ scopename = Copy(fname);
+ }
+ } else {
+ if ((CPlusPlus) || (unnamed)) {
+ SwigType_typedef_class(name);
+ } else {
+ SwigType_typedef_class(NewStringf("%s %s", kind, name));
+ }
+ scopename = Copy(name);
+ }
+ } else {
+ scopename = 0;
+ }
+
+ Setattr(n, "typepass:visit", "1");
+
+ /* Need to set up a typedef if unnamed */
+ if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
+ SwigType_typedef(unnamed, tdname);
+ }
+
+ if (nsname) {
+ nname = NewStringf("%s::%s", nsname, name);
+ String *tdname = Getattr(n, "tdname");
+ if (tdname) {
+ tdname = NewStringf("%s::%s", nsname, tdname);
+ Setattr(n, "tdname", tdname);
+ }
+ }
+ SwigType_new_scope(scopename);
+ SwigType_attach_symtab(Getattr(n, "symtab"));
+
+ /* Inherit type definitions into the class */
+ if (name) {
+ cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
+ }
+
+ inclass = n;
+ symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
+ emit_children(n);
+ Swig_symbol_setscope(symtab);
+
+ Hash *ts = SwigType_pop_scope();
+ Setattr(n, "typescope", ts);
+ Delete(ts);
+ Setattr(n, "module", module);
+
+ /* Normalize deferred types */
+ {
+ normal_node *nn = new normal_node();
+ nn->normallist = normalize;
+ nn->symtab = Getattr(n, "symtab");
+ nn->next = patch_list;
+ nn->typescope = Getattr(n, "typescope");
+ patch_list = nn;
+ }
+
+ normalize = olist;
+
+ inclass = oldinclass;
+
+ /* If in a namespace, patch the class name */
+ if (nname) {
+ Setattr(n, "name", nname);
+ Delete(nname);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * namespaceDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int templateDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+ String *ttype = Getattr(n, "templatetype");
+ if (Strcmp(ttype, "class") == 0) {
+ String *rname = SwigType_typedef_resolve_all(name);
+ SwigType_typedef_class(rname);
+ Delete(rname);
+ } else if (Strcmp(ttype, "classforward") == 0) {
+ String *rname = SwigType_typedef_resolve_all(name);
+ SwigType_typedef_class(rname);
+ Delete(rname);
+ /* SwigType_typedef_class(name); */
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classforwardDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classforwardDeclaration(Node *n) {
+
+ /* Temporary hack. Can't do inside a class because it breaks
+ C nested structure wrapping */
+
+ if ((!inclass) || (CPlusPlus)) {
+ String *name = Getattr(n, "name");
+ String *nname;
+ SwigType_typedef_class(name);
+ if (nsname) {
+ nname = NewStringf("%s::%s", nsname, name);
+ Setattr(n, "name", nname);
+ }
+
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * namespaceDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int namespaceDeclaration(Node *n) {
+ Symtab *symtab;
+ String *name = Getattr(n, "name");
+ String *alias = Getattr(n, "alias");
+ List *olist = normalize;
+ normalize = NewList();
+ if (alias) {
+ Typetab *ts = Getattr(n, "typescope");
+ if (!ts) {
+ Node *ns;
+ /* Create a empty scope for the alias */
+ ns = Getattr(n, "namespace");
+ if (ns) {
+ SwigType_scope_alias(name, Getattr(ns, "typescope"));
+ }
+ ts = Getattr(ns, "typescope");
+ Setattr(n, "typescope", ts);
+ }
+ /* Namespace alias */
+ return SWIG_OK;
+ } else {
+ if (name) {
+ Node *nn = Swig_symbol_clookup(name, n);
+ Hash *ts = 0;
+ if (nn)
+ ts = Getattr(nn, "typescope");
+ if (!ts) {
+ SwigType_new_scope(name);
+ SwigType_attach_symtab(Getattr(n, "symtab"));
+ } else {
+ SwigType_set_scope(ts);
+ }
+ }
+ String *oldnsname = nsname;
+ nsname = Swig_symbol_qualified(Getattr(n, "symtab"));
+ symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
+ emit_children(n);
+ Swig_symbol_setscope(symtab);
+
+ if (name) {
+ Hash *ts = SwigType_pop_scope();
+ Setattr(n, "typescope", ts);
+ Delete(ts);
+ }
+
+ /* Normalize deferred types */
+ {
+ normal_node *nn = new normal_node();
+ nn->normallist = normalize;
+ nn->symtab = Getattr(n, "symtab");
+ nn->next = patch_list;
+ nn->typescope = Getattr(n, "typescope");
+ patch_list = nn;
+ }
+ normalize = olist;
+
+ Delete(nsname);
+ nsname = oldnsname;
+ return SWIG_OK;
+ }
+ }
+
+ /* ------------------------------------------------------------
+ * cDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int cDeclaration(Node *n) {
+ if (NoExcept) {
+ Delattr(n, "throws");
+ }
+
+ /* Normalize types. */
+ SwigType *ty = Getattr(n, "type");
+ normalize_type(ty);
+ SwigType *decl = Getattr(n, "decl");
+ if (decl) {
+ normalize_type(decl);
+ }
+ normalize_parms(Getattr(n, "parms"));
+ normalize_parms(Getattr(n, "throws"));
+ if (GetFlag(n, "conversion_operator")) {
+ /* The call to the operator in the generated wrapper must be fully qualified in order to compile */
+ SwigType *name = Getattr(n, "name");
+ SwigType *qualifiedname = Swig_symbol_string_qualify(name,0);
+ Clear(name);
+ Append(name, qualifiedname);
+ Delete(qualifiedname);
+ }
+
+ if (checkAttribute(n, "storage", "typedef")) {
+ String *name = Getattr(n, "name");
+ ty = Getattr(n, "type");
+ decl = Getattr(n, "decl");
+ SwigType *t = Copy(ty);
+ {
+ /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */
+ if (Swig_scopename_check(t) && strncmp(Char(t), "::", 2)) {
+ String *base, *prefix, *qprefix;
+ base = Swig_scopename_last(t);
+ prefix = Swig_scopename_prefix(t);
+ qprefix = SwigType_typedef_qualified(prefix);
+ Delete(t);
+ t = NewStringf("%s::%s", qprefix, base);
+ Delete(base);
+ Delete(prefix);
+ Delete(qprefix);
+ }
+ }
+ SwigType_push(t, decl);
+ if (CPlusPlus) {
+ Replaceall(t, "struct ", "");
+ Replaceall(t, "union ", "");
+ Replaceall(t, "class ", "");
+ }
+ SwigType_typedef(t, name);
+ }
+ /* If namespaces are active. We need to patch the name with a namespace prefix */
+ if (nsname && !inclass) {
+ String *name = Getattr(n, "name");
+ if (name) {
+ String *nname = NewStringf("%s::%s", nsname, name);
+ Setattr(n, "name", nname);
+ Delete(nname);
+ }
+ }
+ clean_overloaded(n);
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * constructorDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorDeclaration(Node *n) {
+ if (NoExcept) {
+ Delattr(n, "throws");
+ }
+
+ normalize_parms(Getattr(n, "parms"));
+ normalize_parms(Getattr(n, "throws"));
+
+ /* If in a namespace, patch the class name */
+ if (nsname) {
+ String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
+ Setattr(n, "name", nname);
+ }
+ clean_overloaded(n);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorDeclaration(Node *n) {
+ /* If in a namespace, patch the class name */
+ if (nsname) {
+ String *nname = NewStringf("%s::%s", nsname, Getattr(n, "name"));
+ Setattr(n, "name", nname);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int constantDirective(Node *n) {
+ SwigType *ty = Getattr(n, "type");
+ if (ty) {
+ Setattr(n, "type", SwigType_typedef_qualified(ty));
+ }
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * enumDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+
+ if (name) {
+ String *scope = 0;
+
+ // Add a typedef to the type table so that we can use 'enum Name' as well as just 'Name'
+ if (nsname || inclass) {
+
+ // But first correct the name and tdname to contain the fully qualified scopename
+ if (nsname && inclass) {
+ scope = NewStringf("%s::%s", nsname, Getattr(inclass, "name"));
+ } else if (nsname) {
+ scope = NewStringf("%s", nsname);
+ } else if (inclass) {
+ scope = NewStringf("%s", Getattr(inclass, "name"));
+ }
+
+ String *nname = NewStringf("%s::%s", scope, name);
+ Setattr(n, "name", nname);
+
+ String *tdname = Getattr(n, "tdname");
+ if (tdname) {
+ tdname = NewStringf("%s::%s", scope, tdname);
+ Setattr(n, "tdname", tdname);
+ }
+
+ SwigType *t = NewStringf("enum %s", nname);
+ SwigType_typedef(t, name);
+ } else {
+ SwigType *t = NewStringf("enum %s", name);
+ SwigType_typedef(t, name);
+ }
+ Delete(scope);
+ }
+
+ String *tdname = Getattr(n, "tdname");
+ String *unnamed = Getattr(n, "unnamed");
+ String *storage = Getattr(n, "storage");
+
+ // Construct enumtype - for declaring an enum of this type with SwigType_ltype() etc
+ String *enumtype = 0;
+ if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
+ enumtype = Copy(Getattr(n, "tdname"));
+ } else if (name) {
+ enumtype = NewStringf("%s%s", CPlusPlus ? "" : "enum ", Getattr(n, "name"));
+ } else {
+ // anonymous enums
+ enumtype = Copy(Getattr(n, "type"));
+ }
+ Setattr(n, "enumtype", enumtype);
+
+ // This block of code is for dealing with %ignore on an enum item where the target language
+ // attempts to use the C enum value in the target language itself and expects the previous enum value
+ // to be one more than the previous value... the previous enum item might not exist if it is ignored!
+ // - It sets the first non-ignored enum item with the "firstenumitem" attribute.
+ // - It adds an enumvalue attribute if the previous enum item is ignored
+ {
+ Node *c;
+ int count = 0;
+ String *previous = 0;
+ bool previous_ignored = false;
+ bool firstenumitem = false;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ assert(strcmp(Char(nodeType(c)), "enumitem") == 0);
+
+ bool reset;
+ String *enumvalue = Getattr(c, "enumvalue");
+ if (GetFlag(c, "feature:ignore")) {
+ reset = enumvalue ? true : false;
+ previous_ignored = true;
+ } else {
+ if (!enumvalue && previous_ignored) {
+ if (previous)
+ Setattr(c, "enumvalue", NewStringf("(%s) + %d", previous, count+1));
+ else
+ Setattr(c, "enumvalue", NewStringf("%d", count));
+ SetFlag(c, "virtenumvalue"); // identify enumvalue as virtual, ie not from the parsed source
+ }
+ if (!firstenumitem) {
+ SetFlag(c, "firstenumitem");
+ firstenumitem = true;
+ }
+ reset = true;
+ previous_ignored = false;
+ }
+ if (reset) {
+ previous = enumvalue ? enumvalue : Getattr(c, "name");
+ count = 0;
+ } else {
+ count++;
+ }
+ }
+ }
+
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * enumvalueDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+ String *value = Getattr(n, "value");
+ if (!value)
+ value = name;
+ if (Strcmp(value, name) == 0) {
+ String *new_value;
+ if (((nsname) || (inclass)) && cparse_cplusplus) {
+ new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
+ } else {
+ new_value = NewString(value);
+ }
+ Setattr(n, "value", new_value);
+ Delete(new_value);
+ }
+ Node *next = nextSibling(n);
+
+ // 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)
+ if (!GetFlag(n, "feature:ignore")) {
+ if (Getattr(n, "_last") && !Getattr(n, "enumvalue")) { // Only the first enum item has _last set (Note: first non-ignored enum item has firstenumitem set)
+ Setattr(n, "enumvalueex", "0");
+ }
+ if (next && !Getattr(next, "enumvalue")) {
+ Setattr(next, "enumvalueex", NewStringf("%s + 1", Getattr(n, "sym:name")));
+ }
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * enumforwardDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumforwardDeclaration(Node *n) {
+
+ // Use enumDeclaration() to do all the hard work.
+ // Note that no children can be emitted in a forward declaration as there aren't any.
+ return enumDeclaration(n);
+ }
+
+#ifdef DEBUG_OVERLOADED
+ static void show_overloaded(Node *n) {
+ Node *c = Getattr(n, "sym:overloaded");
+ Node *checkoverloaded = c;
+ Printf(stdout, "-------------------- overloaded start %s sym:overloaded():%p -------------------------------\n", Getattr(n, "name"), c);
+ while (c) {
+ if (Getattr(c, "error")) {
+ c = Getattr(c, "sym:nextSibling");
+ continue;
+ }
+ if (Getattr(c, "sym:overloaded") != checkoverloaded) {
+ Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
+ Swig_print_node(c);
+ exit (1);
+ }
+
+ String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
+ 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));
+ if (!Getattr(c, "sym:overloaded")) {
+ Printf(stdout, "sym:overloaded error.....%p\n", c);
+ Swig_print_node(c);
+ exit (1);
+ }
+ c = Getattr(c, "sym:nextSibling");
+ }
+ Printf(stdout, "-------------------- overloaded end %s -------------------------------\n", Getattr(n, "name"));
+ }
+#endif
+
+ /* ------------------------------------------------------------
+ * usingDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int usingDeclaration(Node *n) {
+ if (Getattr(n, "namespace")) {
+ /* using namespace id */
+
+ /* For a namespace import. We set up inheritance in the type system */
+ Node *ns = Getattr(n, "node");
+ if (ns) {
+ Typetab *ts = Getattr(ns, "typescope");
+ if (ts) {
+ SwigType_using_scope(ts);
+ }
+ }
+ return SWIG_OK;
+ } else {
+ Node *ns;
+ /* using id */
+ Symtab *stab = Getattr(n, "sym:symtab");
+ if (stab) {
+ String *uname = Getattr(n, "uname");
+ ns = Swig_symbol_clookup(uname, stab);
+ if (!ns && SwigType_istemplate(uname)) {
+ String *tmp = Swig_symbol_template_deftype(uname, 0);
+ if (!Equal(tmp, uname)) {
+ ns = Swig_symbol_clookup(tmp, stab);
+ }
+ Delete(tmp);
+ }
+ } else {
+ ns = 0;
+ }
+ if (!ns) {
+ if (is_public(n)) {
+ Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname")));
+ }
+ } else {
+ /* Only a single symbol is being used. There are only a few symbols that
+ we actually care about. These are typedef, class declarations, and enum */
+ String *ntype = nodeType(ns);
+ if (Strcmp(ntype, "cdecl") == 0) {
+ if (checkAttribute(ns, "storage", "typedef")) {
+ /* A typedef declaration */
+ String *uname = Getattr(n, "uname");
+ SwigType_typedef_using(uname);
+ } else {
+ /* A normal C declaration. */
+ if ((inclass) && (!GetFlag(n, "feature:ignore")) && (Getattr(n, "sym:name"))) {
+ Node *c = ns;
+ Node *unodes = 0, *last_unodes = 0;
+ int ccount = 0;
+ String *symname = Getattr(n, "sym:name");
+ while (c) {
+ if (Strcmp(nodeType(c), "cdecl") == 0) {
+ if (!(checkAttribute(c, "storage", "static")
+ || checkAttribute(c, "storage", "typedef")
+ || checkAttribute(c, "storage", "friend")
+ || (Getattr(c, "feature:extend") && !Getattr(c, "code"))
+ || GetFlag(c, "feature:ignore"))) {
+
+ /* Don't generate a method if the method is overridden in this class,
+ * for example don't generate another m(bool) should there be a Base::m(bool) :
+ * struct Derived : Base {
+ * void m(bool);
+ * using Base::m;
+ * };
+ */
+ String *csymname = Getattr(c, "sym:name");
+ if (!csymname || (Strcmp(csymname, symname) == 0)) {
+ {
+ String *decl = Getattr(c, "decl");
+ Node *over = Getattr(n, "sym:overloaded");
+ int match = 0;
+ while (over) {
+ String *odecl = Getattr(over, "decl");
+ if (Cmp(decl, odecl) == 0) {
+ match = 1;
+ break;
+ }
+ over = Getattr(over, "sym:nextSibling");
+ }
+ if (match) {
+ c = Getattr(c, "csym:nextSibling");
+ continue;
+ }
+ }
+ Node *nn = copyNode(c);
+ Delattr(nn, "access"); // access might be different from the method in the base class
+ if (!Getattr(nn, "sym:name"))
+ Setattr(nn, "sym:name", symname);
+
+ if (!GetFlag(nn, "feature:ignore")) {
+ ParmList *parms = CopyParmList(Getattr(c, "parms"));
+ int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
+ int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
+ Setattr(nn, "parms", parms);
+ Delete(parms);
+ if (Getattr(n, "feature:extend")) {
+ String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
+
+ for (ParmList *p = parms; p;) {
+ Append(ucode, Getattr(p, "name"));
+ p = nextSibling(p);
+ if (p)
+ Append(ucode, ",");
+ }
+ Append(ucode, "); }");
+ Setattr(nn, "code", ucode);
+ Delete(ucode);
+ }
+ ParmList *throw_parm_list = Getattr(c, "throws");
+ if (throw_parm_list)
+ Setattr(nn, "throws", CopyParmList(throw_parm_list));
+ ccount++;
+ if (!last_unodes) {
+ last_unodes = nn;
+ unodes = nn;
+ } else {
+ Setattr(nn, "previousSibling", last_unodes);
+ Setattr(last_unodes, "nextSibling", nn);
+ Setattr(nn, "sym:previousSibling", last_unodes);
+ Setattr(last_unodes, "sym:nextSibling", nn);
+ Setattr(nn, "sym:overloaded", unodes);
+ Setattr(unodes, "sym:overloaded", unodes);
+ last_unodes = nn;
+ }
+ } else {
+ Delete(nn);
+ }
+ }
+ }
+ }
+ c = Getattr(c, "csym:nextSibling");
+ }
+ if (unodes) {
+ set_firstChild(n, unodes);
+ if (ccount > 1) {
+ if (!Getattr(n, "sym:overloaded")) {
+ Setattr(n, "sym:overloaded", n);
+ Setattr(n, "sym:overname", "_SWIG_0");
+ }
+ }
+ }
+
+ /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
+ * list of overloaded methods we have just added in as child nodes to the "using" node.
+ * The node will still exist, it is just the symbol table linked list of overloaded methods
+ * which is hacked. */
+ if (Getattr(n, "sym:overloaded"))
+ {
+#ifdef DEBUG_OVERLOADED
+show_overloaded(n);
+#endif
+ int cnt = 0;
+ Node *debugnode = n;
+ if (!firstChild(n)) {
+ // Remove from overloaded list ('using' node does not actually end up adding in any methods)
+ Node *ps = Getattr(n, "sym:previousSibling");
+ Node *ns = Getattr(n, "sym:nextSibling");
+ if (ps) {
+ Setattr(ps, "sym:nextSibling", ns);
+ }
+ if (ns) {
+ Setattr(ns, "sym:previousSibling", ps);
+ }
+ } else {
+ // The 'using' node results in methods being added in - slot in the these methods here
+ Node *ps = Getattr(n, "sym:previousSibling");
+ Node *ns = Getattr(n, "sym:nextSibling");
+ Node *fc = firstChild(n);
+ Node *pp = fc;
+
+ Node *firstoverloaded = Getattr(n, "sym:overloaded");
+ if (firstoverloaded == n) {
+ // This 'using' node we are cutting out was the first node in the overloaded list.
+ // Change the first node in the list to its first sibling
+ Delattr(firstoverloaded, "sym:overloaded");
+ Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
+ firstoverloaded = fc;
+ while (nnn) {
+ Setattr(nnn, "sym:overloaded", firstoverloaded);
+ nnn = Getattr(nnn, "sym:nextSibling");
+ }
+ }
+ while (pp) {
+ Node *ppn = Getattr(pp, "sym:nextSibling");
+ Setattr(pp, "sym:overloaded", firstoverloaded);
+ Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
+ if (ppn)
+ pp = ppn;
+ else
+ break;
+ }
+ if (ps) {
+ Setattr(ps, "sym:nextSibling", fc);
+ Setattr(fc, "sym:previousSibling", ps);
+ }
+ if (ns) {
+ Setattr(ns, "sym:previousSibling", pp);
+ Setattr(pp, "sym:nextSibling", ns);
+ }
+ debugnode = firstoverloaded;
+ }
+ Delattr(n, "sym:previousSibling");
+ Delattr(n, "sym:nextSibling");
+ Delattr(n, "sym:overloaded");
+ Delattr(n, "sym:overname");
+#ifdef DEBUG_OVERLOADED
+show_overloaded(debugnode);
+#endif
+ clean_overloaded(n); // Needed?
+ }
+ }
+ }
+ } else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
+ /* We install the using class name as kind of a typedef back to the original class */
+ String *uname = Getattr(n, "uname");
+ /* Import into current type scope */
+ SwigType_typedef_using(uname);
+ } else if (Strcmp(ntype, "enum") == 0) {
+ SwigType_typedef_using(Getattr(n, "uname"));
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * typemapDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int typemapDirective(Node *n) {
+ if (inclass || nsname) {
+ Node *items = firstChild(n);
+ while (items) {
+ Parm *pattern = Getattr(items, "pattern");
+ Parm *parms = Getattr(items, "parms");
+ normalize_later(pattern);
+ normalize_later(parms);
+ items = nextSibling(items);
+ }
+ }
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * typemapcopyDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int typemapcopyDirective(Node *n) {
+ if (inclass || nsname) {
+ Node *items = firstChild(n);
+ ParmList *pattern = Getattr(n, "pattern");
+ normalize_later(pattern);
+ while (items) {
+ ParmList *npattern = Getattr(items, "pattern");
+ normalize_later(npattern);
+ items = nextSibling(items);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * applyDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int applyDirective(Node *n) {
+ if (inclass || nsname) {
+ ParmList *pattern = Getattr(n, "pattern");
+ normalize_later(pattern);
+ Node *items = firstChild(n);
+ while (items) {
+ Parm *apattern = Getattr(items, "pattern");
+ normalize_later(apattern);
+ items = nextSibling(items);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * clearDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int clearDirective(Node *n) {
+ if (inclass || nsname) {
+ Node *p;
+ for (p = firstChild(n); p; p = nextSibling(p)) {
+ ParmList *pattern = Getattr(p, "pattern");
+ normalize_later(pattern);
+ }
+ }
+ return SWIG_OK;
+ }
+
+public:
+ static void pass(Node *n) {
+ TypePass t;
+ t.top(n);
+ }
+};
+
+void Swig_process_types(Node *n) {
+ if (!n)
+ return;
+ TypePass::pass(n);
+}