/trunk/Source/Modules/typepass.cxx
C++ | 1234 lines | 969 code | 115 blank | 150 comment | 257 complexity | 137171621df1b2b2f5de1d4adcbbe976 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
- /* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.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 12953 2012-03-25 19:10:33Z 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;
- String *nssymname;
- 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(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
- Swig_error(Getfile(bcls), Getline(bcls), "See definition of '%s'.\n", SwigType_namestr(bname));
- } else {
- Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bname), Getline(bname), "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(bname), Getline(bname), "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(bname), Getline(bname), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
- if (Strchr(bname, '<')) {
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "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);
- String *smartptr = Getattr(first, "feature:smartptr");
- if (smartptr) {
- SwigType *smart = 0;
- SwigType *spt = Swig_cparse_type(smartptr);
- if (spt) {
- smart = SwigType_typedef_resolve_all(spt);
- Delete(spt);
- /* Record a (fake) inheritance relationship between smart pointer
- and smart pointer to base class, so that smart pointer upcasts
- are automatically generated. */
- SwigType *bsmart = Copy(smart);
- SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
- SwigType *rbname = SwigType_typedef_resolve_all(bname);
- Replaceall(bsmart, rclsname, rbname);
- Delete(rclsname);
- Delete(rbname);
- String *smartnamestr = SwigType_namestr(smart);
- String *bsmartnamestr = SwigType_namestr(bsmart);
- /* construct casting code */
- String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
- Delete(bsmartnamestr);
- Delete(smartnamestr);
- /* setup inheritance relationship between smart pointer templates */
- SwigType_inherit(smart, bsmart, 0, convcode);
- if (!GetFlag(bclass, "feature:smartptr"))
- Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
- Delete(convcode);
- Delete(bsmart);
- Delete(smart);
- } else {
- Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(smartptr), SwigType_namestr(clsname));
- }
- } else {
- if (GetFlag(bclass, "feature:smartptr"))
- Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name")));
- }
- 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", SwigType_namestr(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;
- nssymname = 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;
- String *template_default_expanded = 0;
- normalize = NewList();
- if (name) {
- if (SwigType_istemplate(name)) {
- // We need to fully resolve the name and expand default template parameters to make templates work correctly */
- Node *cn;
- SwigType *resolved_name = SwigType_typedef_resolve_all(name);
- SwigType *deftype_name = Swig_symbol_template_deftype(resolved_name, 0);
- fname = Copy(resolved_name);
- if (!Equal(resolved_name, deftype_name))
- template_default_expanded = Copy(deftype_name);
- if (!Equal(fname, name) && (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);
- if (template_default_expanded)
- Swig_symbol_cadd(template_default_expanded, 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);
- }
- Delete(deftype_name);
- Delete(resolved_name);
- } 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 && name) {
- nname = NewStringf("%s::%s", nsname, name);
- String *tdname = Getattr(n, "tdname");
- if (tdname) {
- tdname = NewStringf("%s::%s", nsname, tdname);
- Setattr(n, "tdname", tdname);
- }
- }
- if (nssymname) {
- if (GetFlag(n, "feature:nspace"))
- Setattr(n, "sym:nspace", nssymname);
- }
- 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);
- // When a fully qualified templated type with default parameters is used in the parsed code,
- // the following additional symbols and scopes are needed for successful lookups
- if (template_default_expanded) {
- Swig_symbol_alias(template_default_expanded, Getattr(n, "symtab"));
- SwigType_scope_alias(template_default_expanded, Getattr(n, "typescope"));
- }
- /* 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);
- }
- Delete(fname);
- 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) {
- /* Can't do inside a C struct because it breaks C nested structure wrapping */
- if ((!inclass) || (CPlusPlus)) {
- String *name = Getattr(n, "name");
- SwigType_typedef_class(name);
- }
- 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;
- String *oldnssymname = nssymname;
- nsname = Swig_symbol_qualified(Getattr(n, "symtab"));
- nssymname = Swig_symbol_qualified_language_scopename(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(nssymname);
- nssymname = oldnssymname;
- 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);
- if (nssymname) {
- if (GetFlag(n, "feature:nspace"))
- Setattr(n, "sym:nspace", nssymname);
- }
- // 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") || !Getattr(c, "sym:name")) {
- 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);
- }
- if ((nsname || inclass) && !cparse_cplusplus) {
- String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
- Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */
- }
- 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
- Setattr(nn, "access", Getattr(n, "access"));
- 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"))
- {
- int cnt = 0;
- #ifdef DEBUG_OVERLOADED
- Node *debugnode = n;
- show_overloaded(n);
- #endif
- 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);
- }
- #ifdef DEBUG_OVERLOADED
- debugnode = firstoverloaded;
- #endif
- }
- 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);
- }