Fix overloading of shared_ptr method overloading

Add 'equivalent' attribute to typecheck typemap.
Closes #1098.
This commit is contained in:
William S Fulton 2017-09-23 14:46:44 +01:00
commit ed4b84f4d3
24 changed files with 378 additions and 15 deletions

View file

@ -12,6 +12,7 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
#include "cparse.h"
/* -----------------------------------------------------------------------------
* emit_return_variable()
@ -112,9 +113,8 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
/* This is compatibility code to deal with the deprecated "ignore" typemap */
Parm *p = l;
Parm *np;
String *tm;
while (p) {
tm = Getattr(p, "tmap:in");
String *tm = Getattr(p, "tmap:in");
if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) {
Replaceall(tm, "$target", Getattr(p, "lname"));
Printv(f->code, tm, "\n", NIL);
@ -134,7 +134,6 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
/* Perform a sanity check on "in" and "freearg" typemaps. These
must exactly match to avoid chaos. If a mismatch occurs, we
nuke the freearg typemap */
{
Parm *p = l;
Parm *npin, *npfreearg;
@ -196,6 +195,36 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
}
}
}
/*
* An equivalent type can be used in the typecheck typemap for SWIG to detect the overloading of equivalent
* target language types. This is primarily for the smartptr feature, where a pointer and a smart pointer
* are seen as equivalent types in the target language.
*/
{
Parm *p = l;
while (p) {
String *tm = Getattr(p, "tmap:typecheck");
if (tm) {
String *equivalent = Getattr(p, "tmap:typecheck:equivalent");
if (equivalent) {
String *precedence = Getattr(p, "tmap:typecheck:precedence");
if (precedence && Strcmp(precedence, "0") != 0)
Swig_error(Getfile(tm), Getline(tm), "The 'typecheck' typemap for %s contains an 'equivalent' attribute for a 'precedence' that is not set to SWIG_TYPECHECK_POINTER or 0.\n", SwigType_str(Getattr(p, "type"), 0));
SwigType *cpt = Swig_cparse_type(equivalent);
if (cpt) {
Setattr(p, "equivtype", cpt);
Delete(cpt);
} else {
Swig_error(Getfile(tm), Getline(tm), "Invalid type (%s) in 'equivalent' attribute in 'typecheck' typemap for type %s.\n", equivalent, SwigType_str(Getattr(p, "type"), 0));
}
}
p = Getattr(p, "tmap:typecheck:next");
} else {
p = nextSibling(p);
}
}
}
}
/* -----------------------------------------------------------------------------

View file

@ -185,7 +185,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
nodes[j] = t;
break;
} else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
t1 = Getattr(p1, "ltype");
t1 = Getattr(p1, "equivtype");
t1 = t1 ? t1 : Getattr(p1, "ltype");
if (!t1) {
t1 = SwigType_ltype(Getattr(p1, "type"));
if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
@ -193,7 +194,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
}
Setattr(p1, "ltype", t1);
}
t2 = Getattr(p2, "ltype");
t2 = Getattr(p2, "equivtype");
t2 = t2 ? t2 : Getattr(p2, "ltype");
if (!t2) {
t2 = SwigType_ltype(Getattr(p2, "type"));
if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {