diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2010-05-22 22:49:47 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2010-05-22 22:49:47 +0000 |
commit | 12cfc251e423a526811b84ccb0f11fd7684cbc56 (patch) | |
tree | 836a89c3c8e781b3d5650c31a6fe2f3ee447daf8 /Source | |
parent | 1fe29bae873b2c389a5bcdbfbc54dae9e7851d1b (diff) | |
download | swig-12cfc251e423a526811b84ccb0f11fd7684cbc56.tar.gz |
Fix #2408232. Improve shared_ptr and intrusive_ptr wrappers for classes in an inheritance hierarchy. No special treatment is needed for derived classes, the SWIG_SHARED_PTR_DERIVED macro is deprecated.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12036 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Source')
-rw-r--r-- | Source/Modules/csharp.cxx | 36 | ||||
-rw-r--r-- | Source/Modules/java.cxx | 52 | ||||
-rw-r--r-- | Source/Modules/typepass.cxx | 31 |
3 files changed, 104 insertions, 15 deletions
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index bedaae7f2..ba8f34b47 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1817,7 +1817,8 @@ public: // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGUpcast"); + String *smartptr = Getattr(n, "feature:smartptr"); + String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); String *wname = Swig_name_wrapper(upcast_method); Printv(imclass_cppcasts_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); @@ -1825,10 +1826,35 @@ public: Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); - Printv(upcasts_code, - "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, - "(", c_classname, " *jarg1) {\n", " return (", c_baseclass, " *)jarg1;\n" "}\n", "\n", NIL); - + if (smartptr) { + SwigType *spt = Swig_cparse_type(smartptr); + if (spt) { + SwigType *smart = SwigType_typedef_resolve_all(spt); + Delete(spt); + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + 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(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, c_classname); + } + } else { + Printv(upcasts_code, + "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n", + " return (", c_baseclass, " *)jarg1;\n" + "}\n", "\n", NIL); + } Delete(wname); Delete(upcast_method); } diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index ee68af948..8c4770a9e 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1825,19 +1825,51 @@ public: // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGUpcast"); + String *smartptr = Getattr(n, "feature:smartptr"); + String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); String *jniname = makeValidJniName(upcast_method); String *wname = Swig_name_wrapper(jniname); - Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method); - - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " (void)jenv;\n" " (void)jcls;\n" " *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n" - " return baseptr;\n" - "}\n", "\n", NIL); - + if (smartptr) { + SwigType *spt = Swig_cparse_type(smartptr); + if (spt) { + SwigType *smart = SwigType_typedef_resolve_all(spt); + Delete(spt); + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " ", smartnamestr, " *argp1;\n" + " ", bsmartnamestr, " result;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " argp1 = *(", smartnamestr, " **)&jarg1;\n" + " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + Delete(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, c_classname); + } + } else { + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + } Delete(wname); Delete(jniname); Delete(upcast_method); diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index e63b58a10..57a7663eb 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -231,6 +231,37 @@ class TypePass:private Dispatcher { 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); + Delete(convcode); + Delete(bsmart); + Delete(smart); + } else { + Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, clsname); + } + } if (!importmode) { String *btype = Copy(bname); SwigType_add_pointer(btype); |