mirror of https://github.com/swig/swig
SwigType * handling corrections
Further corrections to pass SwigType * to methods expecting types instead of passing readable type strings. Required reworking code that adds a fake inheritance for smart pointers using the smartptr feature. Swig_smartptr_upcast() added as a support function for this.
This commit is contained in:
parent
ea3f043920
commit
2acdfd77e9
|
@ -1744,35 +1744,32 @@ public:
|
|||
|
||||
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
|
||||
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
if (smart) {
|
||||
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
|
||||
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
|
||||
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
|
||||
" return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
|
||||
"}\n", "\n", NIL);
|
||||
|
||||
Delete(rbaseclassname);
|
||||
Delete(rclassname);
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
} else {
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
|
||||
" return (", baseclassname, " *)jarg1;\n"
|
||||
"}\n", "\n", NIL);
|
||||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
}
|
||||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
Delete(wname);
|
||||
}
|
||||
|
||||
|
|
|
@ -3374,19 +3374,15 @@ private:
|
|||
String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast"));
|
||||
String *upcast_wrapper_name = Swig_name_wrapper(upcast_name);
|
||||
|
||||
writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)",
|
||||
upcast_wrapper_name);
|
||||
writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)", upcast_wrapper_name);
|
||||
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
if (smart) {
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
|
||||
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
|
||||
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
|
||||
if (smart) {
|
||||
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
|
||||
|
@ -3395,10 +3391,9 @@ private:
|
|||
"}\n",
|
||||
"\n", NIL);
|
||||
|
||||
Delete(rbaseclassname);
|
||||
Delete(rclassname);
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
} else {
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
|
||||
|
@ -3413,8 +3408,8 @@ private:
|
|||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
Delete(upcast_name);
|
||||
Delete(upcast_wrapper_name);
|
||||
Delete(upcast_name);
|
||||
Delete(smart);
|
||||
}
|
||||
|
||||
|
|
|
@ -1883,16 +1883,10 @@ public:
|
|||
|
||||
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name);
|
||||
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
if (smart) {
|
||||
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
|
||||
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
|
||||
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
|
||||
|
@ -1905,11 +1899,13 @@ public:
|
|||
" return baseptr;\n"
|
||||
"}\n", "\n", NIL);
|
||||
|
||||
Delete(rbaseclassname);
|
||||
Delete(rclassname);
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
} else {
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
|
||||
" jlong baseptr = 0;\n"
|
||||
|
@ -1918,10 +1914,11 @@ public:
|
|||
" *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n"
|
||||
" return baseptr;\n"
|
||||
"}\n", "\n", NIL);
|
||||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
}
|
||||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
Delete(wname);
|
||||
Delete(jniname);
|
||||
}
|
||||
|
|
|
@ -423,6 +423,7 @@ void Wrapper_cast_dispatch_mode_set(int);
|
|||
void Wrapper_naturalvar_mode_set(int);
|
||||
|
||||
void clean_overloaded(Node *n);
|
||||
SwigType *Swig_smartptr_upcast(SwigType *smart, SwigType *c_classname, SwigType *c_baseclassname);
|
||||
|
||||
extern "C" {
|
||||
const char *Swig_to_string(DOH *object, int count = -1);
|
||||
|
|
|
@ -254,7 +254,7 @@ class TypePass:private Dispatcher {
|
|||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
Node *n = Getitem(ilist, i);
|
||||
String *bname = Getattr(n, "name");
|
||||
SwigType *bname = Getattr(n, "name");
|
||||
Node *bclass = n; /* Getattr(n,"class"); */
|
||||
Hash *scopes = Getattr(bclass, "typescope");
|
||||
SwigType_inherit(clsname, bname, cast, 0);
|
||||
|
@ -266,36 +266,20 @@ class TypePass:private Dispatcher {
|
|||
/* 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);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
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);
|
||||
}
|
||||
// The code above currently creates a smartptr of the base class by substitution, replacing Derived
|
||||
// with Base resulting in something like: 'smartptr< Derived >' from 'smartptr< Base >'. Instead
|
||||
// the feature:smartptr should be used as it also contains 'smartptr< Base >' as specified by the user.
|
||||
// A similar fix should also be done in upcastsCode in java.cxx, csharp.cxx and writeClassUpcast in d.cxx.
|
||||
// Printf(stdout, "smartcomparison %s <=> %s\n", SwigType_namestr(bsmart), Getattr(bclass, "feature:smartptr"));
|
||||
|
||||
Delete(rclsname);
|
||||
Delete(rbname);
|
||||
SwigType *bsmart = Swig_smartptr_upcast(smart, clsname, bname);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -115,6 +115,68 @@ void Swig_set_max_hash_expand(int count) {
|
|||
SetMaxHashExpand(count);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* misc_identifier_fix()
|
||||
*
|
||||
* If a template, return template with all template parameters fully resolved.
|
||||
*
|
||||
* This is a copy and modification of feature_identifier_fix and typemap_identifier_fix.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static SwigType *misc_identifier_fix(const SwigType *s) {
|
||||
String *tp = SwigType_istemplate_templateprefix(s);
|
||||
if (tp) {
|
||||
String *ts, *ta, *tq, *tr;
|
||||
ts = SwigType_templatesuffix(s);
|
||||
ta = SwigType_templateargs(s);
|
||||
tq = Swig_symbol_type_qualify(ta, 0);
|
||||
tr = SwigType_typedef_resolve_all(ta);
|
||||
Append(tp, tr);
|
||||
Append(tp, ts);
|
||||
Delete(ts);
|
||||
Delete(ta);
|
||||
Delete(tq);
|
||||
Delete(tr);
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_smartptr_upcast()
|
||||
*
|
||||
* Replace classname with baseclassname in smart (smart pointer) to morph smart into a
|
||||
* smart pointer containing the base class instead of the given classname.
|
||||
* All parameters should be fully qualified types.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
SwigType *Swig_smartptr_upcast(SwigType *smart, SwigType *classname, SwigType *baseclassname) {
|
||||
SwigType *bsmart = Copy(smart);
|
||||
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
|
||||
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
|
||||
|
||||
int replace_count = Replaceall(bsmart, rclassname, rbaseclassname);
|
||||
if (replace_count == 0) {
|
||||
// If no replacement made, it will be because rclassname is fully resolved, but the
|
||||
// type in the smartptr feature used a typedef or is not a fully resolved name.
|
||||
replace_count = Replaceall(bsmart, classname, rbaseclassname);
|
||||
if (replace_count == 0) {
|
||||
// Next try with all the template parameters in the smartptr resolved
|
||||
Delete(bsmart);
|
||||
SwigType *bsmart = misc_identifier_fix(smart);
|
||||
if (bsmart) {
|
||||
replace_count = Replaceall(bsmart, rclassname, rbaseclassname);
|
||||
}
|
||||
assert(replace_count); // failed to substitute
|
||||
}
|
||||
}
|
||||
|
||||
Delete(rbaseclassname);
|
||||
Delete(rclassname);
|
||||
return bsmart;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
@ -69,6 +69,8 @@ static Hash *typemaps;
|
|||
* resolving the template parameters.
|
||||
*
|
||||
* This is a copy and modification of feature_identifier_fix in parser.y.
|
||||
* Also, Swig_smartptr_upcast() could be removed if SwigType_typedef_resolve_all
|
||||
* is fixed to resolve all template parameters like below.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static SwigType *typemap_identifier_fix(const SwigType *s) {
|
||||
|
@ -102,6 +104,7 @@ static Hash *get_typemap(const SwigType *type) {
|
|||
dtype = Swig_symbol_type_qualify(ty, 0);
|
||||
type = dtype;
|
||||
Delete(ty);
|
||||
Delete(rty);
|
||||
}
|
||||
|
||||
/* remove unary scope operator (::) prefix indicating global scope for looking up in the hashmap */
|
||||
|
|
Loading…
Reference in New Issue