aboutsummaryrefslogtreecommitdiff
path: root/Source/Modules/typepass.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/typepass.cxx')
-rw-r--r--Source/Modules/typepass.cxx247
1 files changed, 37 insertions, 210 deletions
diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx
index 8dbf0865e..aa35c4ec7 100644
--- a/Source/Modules/typepass.cxx
+++ b/Source/Modules/typepass.cxx
@@ -4,7 +4,7 @@
* 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.
+ * and at https://www.swig.org/legal.html.
*
* typepass.cxx
*
@@ -253,47 +253,35 @@ class TypePass:private Dispatcher {
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"); */
+ Node *bclass = Getitem(ilist, i);
+ SwigType *bname = Getattr(bclass, "name");
Hash *scopes = Getattr(bclass, "typescope");
SwigType_inherit(clsname, bname, cast, 0);
if (ispublic && !GetFlag(bclass, "feature:ignore")) {
- String *smartptr = Getattr(first, "feature:smartptr");
- if (smartptr) {
- SwigType *smart = Swig_cparse_smartptr(first);
- if (smart) {
- /* 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);
- int replace_count = Replaceall(bsmart, rclsname, rbname);
- if (replace_count == 0) {
- // If no replacement made, it will be because rclsname is fully resolved, but the
- // type in the smartptr feature used a typedef or not fully resolved name.
- String *firstname = Getattr(first, "name");
- Replaceall(bsmart, firstname, rbname);
- }
- Delete(rclsname);
- Delete(rbname);
+ String *smart = Getattr(first, "smart");
+ if (smart) {
+ /* Record a (fake) inheritance relationship between smart pointer
+ and smart pointer to base class, so that smart pointer upcasts
+ are automatically generated. */
+ SwigType *bsmart = Getattr(bclass, "smart");
+ if (bsmart) {
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(bsmartnamestr);
+ Delete(smartnamestr);
Delete(convcode);
- Delete(bsmart);
+ } else {
+ 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(smart);
} else {
- if (GetFlag(bclass, "feature:smartptr"))
+ if (GetFlag(bclass, "smart"))
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")));
}
}
@@ -454,8 +442,10 @@ class TypePass:private Dispatcher {
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")));
+ // Arguably the parser should instead ignore these duplicate template instantiations, in particular for ensuring the first parsed instantiation is used
+ SetFlag(n, "feature:ignore");
+ Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Duplicate template instantiation of '%s' with name '%s' ignored,\n", SwigType_namestr(name), Getattr(n, "sym:name"));
+ Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous instantiation of '%s' with name '%s'.\n", SwigType_namestr(Getattr(cn, "name")), Getattr(cn, "sym:name"));
scopename = 0;
}
} else {
@@ -510,6 +500,16 @@ class TypePass:private Dispatcher {
SwigType_new_scope(scopename);
SwigType_attach_symtab(Getattr(n, "symtab"));
+ if (!GetFlag(n, "feature:ignore")) {
+ SwigType *smart = Swig_cparse_smartptr(n);
+ if (smart) {
+ // Resolve the type in 'feature:smartptr' in the scope of the class it is attached to
+ normalize_type(smart);
+ Setattr(n, "smart", smart);
+ Delete(smart);
+ }
+ }
+
/* Inherit type definitions into the class */
if (name && !(GetFlag(n, "nested") && !checkAttribute(n, "access", "public") &&
(GetFlag(n, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None))) {
@@ -961,7 +961,7 @@ class TypePass:private Dispatcher {
if (Getattr(c, "sym:overloaded") != checkoverloaded) {
Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
Swig_print_node(c);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
@@ -969,7 +969,7 @@ class TypePass:private Dispatcher {
if (!Getattr(c, "sym:overloaded")) {
Printf(stdout, "sym:overloaded error.....%p\n", c);
Swig_print_node(c);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
c = Getattr(c, "sym:nextSibling");
}
@@ -1011,189 +1011,16 @@ class TypePass:private Dispatcher {
} 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 {
+ // Note that Allocate::usingDeclaration will warn when using member is not found (when ns is zero)
+ if (ns) {
/* 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 (Equal(ntype, "cdecl") || Equal(ntype, "constructor")) {
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 (!(Swig_storage_isstatic(c)
- || 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 */