summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2010-05-22 22:49:47 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2010-05-22 22:49:47 +0000
commit12cfc251e423a526811b84ccb0f11fd7684cbc56 (patch)
tree836a89c3c8e781b3d5650c31a6fe2f3ee447daf8 /Source
parent1fe29bae873b2c389a5bcdbfbc54dae9e7851d1b (diff)
downloadswig-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.cxx36
-rw-r--r--Source/Modules/java.cxx52
-rw-r--r--Source/Modules/typepass.cxx31
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);