diff --git a/CHANGES.current b/CHANGES.current index 3c662f6a8..c545169d4 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.2.1 (in progress) =========================== +2024-01-31: wsfulton + #2768 Fix seg fault handling upcasting when using %shared_ptr on some + templates. + 2024-01-31: olly #2783 Fix incorrectly deduced type for function call. Regression introduced in 4.2.0. diff --git a/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i b/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i new file mode 100644 index 000000000..f00dc1ff4 --- /dev/null +++ b/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i @@ -0,0 +1,92 @@ +%module cpp11_shared_ptr_crtp_upcast + +// Cutdown testcase for assert reported in https://github.com/swig/swig/issues/2768 +// Note that this test has CRTP and %template instantiations for DiscretisedDensity template parameters not fully resolved + +%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, + SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_RUBY_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) stir::DiscretisedDensity<3,float>; + +%include + +%{ +#include +namespace stir {} +using namespace stir; +%} + +%inline %{ +namespace stir { + // Note: CRTP + template + class RegisteredParsingObject : public Parent { + }; +} +%} + +%shared_ptr(stir::Array<3,float>) +%inline %{ +namespace stir { + template + class Array { + }; +} +%} +%template(FloatArray3D) stir::Array<3,float>; + +%shared_ptr(stir::ExamData); +%inline %{ +namespace stir { + class ExamData { + }; +} +%} + +%shared_ptr(stir::DiscretisedDensity<3,float>) +%inline %{ +namespace stir { + template + class DiscretisedDensity : public ExamData, public Array { + }; +} +%} + +%shared_ptr(stir::DataProcessor >) +%shared_ptr(stir::RegisteredParsingObject< + stir::ChainedDataProcessor >, + stir::DataProcessor >, + stir::DataProcessor > >) +%shared_ptr(stir::ChainedDataProcessor >) + +%inline %{ +namespace stir { + template + class DataProcessor { + }; + + template + class ChainedDataProcessor : public RegisteredParsingObject< ChainedDataProcessor, DataProcessor, DataProcessor > { + }; +} +%} + +// SWIG will qualify Discretised in the %template() declaration even though Discretised +// is not in scope with the 'using namespace stir' below commented out. +//using namespace stir; +%template(Float3DDiscretisedDensity) stir::DiscretisedDensity<3,float>; +%template(DataProcessor3DFloat) stir::DataProcessor >; +%template(RPChainedDataProcessor3DFloat) stir::RegisteredParsingObject< + stir::ChainedDataProcessor >, + stir::DataProcessor >, + stir::DataProcessor > >; +%template(ChainedDataProcessor3DFloat) stir::ChainedDataProcessor >; + +%inline %{ +void useobject(stir::RegisteredParsingObject< + stir::ChainedDataProcessor >, + stir::DataProcessor >, + stir::DataProcessor > >) { +} +%} diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in index ca5a59160..6bda2ab56 100644 --- a/Examples/test-suite/csharp/Makefile.in +++ b/Examples/test-suite/csharp/Makefile.in @@ -41,6 +41,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_template_upcast \ diff --git a/Examples/test-suite/d/Makefile.in b/Examples/test-suite/d/Makefile.in index c9ece6140..10eddf17a 100644 --- a/Examples/test-suite/d/Makefile.in +++ b/Examples/test-suite/d/Makefile.in @@ -18,6 +18,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_upcast \ diff --git a/Examples/test-suite/errors/cpp_smartptr_feature.i b/Examples/test-suite/errors/cpp_smartptr_feature.i new file mode 100644 index 000000000..4a0d510cd --- /dev/null +++ b/Examples/test-suite/errors/cpp_smartptr_feature.i @@ -0,0 +1,14 @@ +%module xxx + +%feature("smartptr", noblock=1) AA { std::shared_ptr< AA > } +%feature("smartptr", noblock=1) DD { std::shared_ptr< } + + +struct AA {}; +struct BB : AA {}; +struct CC : AA {}; +struct DD : AA {}; + +%feature("smartptr", noblock=1) YY { std::shared_ptr< YY > } +struct XX {}; +struct YY : XX {}; diff --git a/Examples/test-suite/errors/cpp_smartptr_feature.stderr b/Examples/test-suite/errors/cpp_smartptr_feature.stderr new file mode 100644 index 000000000..442f795ac --- /dev/null +++ b/Examples/test-suite/errors/cpp_smartptr_feature.stderr @@ -0,0 +1,5 @@ +cpp_smartptr_feature.i:8: Warning 520: Derived class 'BB' of 'AA' is not similarly marked as a smart pointer. +cpp_smartptr_feature.i:9: Warning 520: Derived class 'CC' of 'AA' is not similarly marked as a smart pointer. +cpp_smartptr_feature.i:10: Error: Invalid type (std::shared_ptr<) in 'smartptr' feature for class DD. +cpp_smartptr_feature.i:10: Warning 520: Derived class 'DD' of 'AA' is not similarly marked as a smart pointer. +cpp_smartptr_feature.i:14: Warning 520: Base class 'XX' of 'YY' is not similarly marked as a smart pointer. diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in index 00ebb100b..83335d4d4 100644 --- a/Examples/test-suite/java/Makefile.in +++ b/Examples/test-suite/java/Makefile.in @@ -55,6 +55,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_template_upcast \ diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index 3de1f72fc..78d4dec92 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -26,6 +26,7 @@ CPP_TEST_CASES += \ CPP11_TEST_CASES += \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_upcast \ diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index 5e7e8b3ec..fca2d3ff5 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -90,6 +90,7 @@ CPP_TEST_CASES += \ CPP11_TEST_CASES = \ cpp11_hash_tables \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_template_upcast \ diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in index c831f1940..9171b84ce 100644 --- a/Examples/test-suite/ruby/Makefile.in +++ b/Examples/test-suite/ruby/Makefile.in @@ -44,6 +44,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_hash_tables \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_upcast \ diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 39b9a8e27..3afdb2b8b 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -321,7 +321,14 @@ Hash *Swig_cparse_features(void) { return features_hash; } -/* Fully qualify any template parameters */ +/* ----------------------------------------------------------------------------- + * feature_identifier_fix() + * + * If a template, return template with all template parameters fully resolved. + * + * This is a copy and modification of typemap_identifier_fix. + * ----------------------------------------------------------------------------- */ + static String *feature_identifier_fix(String *s) { String *tp = SwigType_istemplate_templateprefix(s); if (tp) { diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 45a396f5a..d217b5fd0 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1729,6 +1729,7 @@ public: Node *base = it.item; SwigType *c_baseclassname = Getattr(base, "name"); String *interface_name = Getattr(base, "interface:name"); + SwigType *bsmart = Getattr(base, "smart"); if (Len(interface_list)) Append(interface_list, ", "); Append(interface_list, interface_name); @@ -1747,7 +1748,7 @@ public: Replaceall(cptr_method_name, "$interfacename", interface_name); String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); Delete(cptr_method_name); @@ -1761,7 +1762,7 @@ public: * Add code for C++ casting to base class * ----------------------------------------------------------------------------- */ - void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { + void upcastsCode(SwigType *smart, SwigType *bsmart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { String *wname = Swig_name_wrapper(upcast_method_name); Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); @@ -1770,18 +1771,18 @@ public: Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); if (smart) { - SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); + if (bsmart) { + 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); + 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); + Delete(bsmartnamestr); + Delete(smartnamestr); + } } else { String *classname = SwigType_namestr(c_classname); String *baseclassname = SwigType_namestr(c_baseclassname); @@ -1811,7 +1812,8 @@ public: SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); bool feature_director = Swig_directorclass(n) ? true : false; bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); + SwigType *bsmart = 0; // Inheritance from pure C# classes Node *attributes = NewHash(); @@ -1833,6 +1835,7 @@ public: if (name) { c_baseclassname = baseclassname; baseclass = name; + bsmart = Getattr(base.item, "smart"); } } else { /* Warn about multiple inheritance for additional base class(es) */ @@ -2070,11 +2073,9 @@ public: if (derived) { String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); } - - Delete(smart); } /* ---------------------------------------------------------------------- @@ -3809,7 +3810,8 @@ public: String *qualified_classname = Copy(sym_name); String *nspace = getNSpace(); String *dirClassName = directorClassName(n); - String *smartptr = Getattr(n, "feature:smartptr"); + SwigType *smart = Getattr(n, "smart"); + String *smartptr = smart ? SwigType_namestr(smart) : 0; if (!GetFlag(n, "feature:flatnested")) { for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 6fed3af4b..3bcee6b39 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -3183,6 +3183,7 @@ private: String *c_baseclassname = NULL; Node *basenode = NULL; String *baseclass = NULL; + SwigType *bsmart = 0; // Inheritance from pure D classes. Node *attributes = NewHash(); @@ -3206,6 +3207,7 @@ private: if (name) { c_baseclassname = baseclassname; baseclass = name; + bsmart = Getattr(base.item, "smart"); } } else { /* Warn about multiple inheritance for additional base class(es) */ @@ -3244,7 +3246,7 @@ private: // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - writeClassUpcast(n, proxy_class_name, c_classname, c_baseclassname); + writeClassUpcast(n, bsmart, proxy_class_name, c_classname, c_baseclassname); } /* @@ -3405,9 +3407,9 @@ private: /* --------------------------------------------------------------------------- * D::writeClassUpcast() * --------------------------------------------------------------------------- */ - void writeClassUpcast(Node *n, const String* d_class_name, SwigType* c_classname, SwigType* c_baseclassname) { + void writeClassUpcast(Node *n, SwigType *bsmart, const String *d_class_name, SwigType *c_classname, SwigType *c_baseclassname) { - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast")); String *upcast_wrapper_name = Swig_name_wrapper(upcast_name); @@ -3417,20 +3419,20 @@ private: 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(bsmart); + if (bsmart) { + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); - Printv(upcasts_code, - "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name, - "(", smartnamestr, " *objectRef) {\n", - " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n" - "}\n", - "\n", NIL); + Printv(upcasts_code, + "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name, + "(", smartnamestr, " *objectRef) {\n", + " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n" + "}\n", + "\n", NIL); - Delete(bsmartnamestr); - Delete(smartnamestr); - Delete(bsmart); + Delete(bsmartnamestr); + Delete(smartnamestr); + } } else { Printv(upcasts_code, "SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name, @@ -3447,7 +3449,6 @@ private: Delete(classname); Delete(upcast_wrapper_name); Delete(upcast_name); - Delete(smart); } /* --------------------------------------------------------------------------- diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 203485831..e35dbcb3b 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1808,6 +1808,7 @@ public: Node *base = it.item; SwigType *c_baseclassname = Getattr(base, "name"); String *interface_name = Getattr(base, "interface:name"); + SwigType *bsmart = Getattr(base, "smart"); if (Len(interface_list)) Append(interface_list, ", "); Append(interface_list, interface_name); @@ -1826,7 +1827,7 @@ public: Replaceall(cptr_method_name, "$interfacename", interface_name); String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); Delete(cptr_method_name); @@ -1840,31 +1841,31 @@ public: * Add code for C++ casting to base class * ----------------------------------------------------------------------------- */ - void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { + void upcastsCode(SwigType *smart, SwigType *bsmart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { String *jniname = makeValidJniName(upcast_method_name); String *wname = Swig_name_wrapper(jniname); Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name); if (smart) { - SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); + if (bsmart) { + 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" - " (void)jenv;\n" - " (void)jcls;\n" - " argp1 = *(", smartnamestr, " **)&jarg1;\n" - " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" - " return baseptr;\n" - "}\n", "\n", NIL); + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " ", smartnamestr, " *argp1;\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); + Delete(bsmartnamestr); + Delete(smartnamestr); + } } else { String *classname = SwigType_namestr(c_classname); String *baseclassname = SwigType_namestr(c_baseclassname); @@ -1899,7 +1900,8 @@ public: SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); bool feature_director = Swig_directorclass(n) ? true : false; bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); + SwigType *bsmart = 0; // Inheritance from pure Java classes Node *attributes = NewHash(); @@ -1921,6 +1923,7 @@ public: if (name) { c_baseclassname = baseclassname; baseclass = name; + bsmart = Getattr(base.item, "smart"); } } else { /* Warn about multiple inheritance for additional base class(es) */ @@ -2068,11 +2071,9 @@ public: if (derived) { String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); } - - Delete(smart); } /* ---------------------------------------------------------------------- @@ -3790,7 +3791,8 @@ public: String *norm_name = SwigType_namestr(Getattr(n, "name")); String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect"); String *swig_director_connect_jni = makeValidJniName(swig_director_connect); - String *smartptr = Getattr(n, "feature:smartptr"); + SwigType *smart = Getattr(n, "smart"); + String *smartptr = smart ? SwigType_namestr(smart) : 0; String *dirClassName = directorClassName(n); Wrapper *code_wrap; @@ -3836,7 +3838,7 @@ public: "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n", jnipackage, jni_imclass_name, changeown_jnimethod_name); - if (Len(smartptr)) { + if (smartptr) { Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr); Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index a16858d2a..a85320b92 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -964,13 +964,14 @@ public: SwigType_add_pointer(t); // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers) - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); String *wrap_class = NewStringf("&_wrap_class_%s", class_name); if (smart) { - SwigType_add_pointer(smart); - SwigType_remember_clientdata(smart, wrap_class); + SwigType *psmart = Copy(smart); + SwigType_add_pointer(psmart); + SwigType_remember_clientdata(psmart, wrap_class); + Delete(psmart); } - //String *wrap_class = NewStringf("&_wrap_class_%s", class_name); SwigType_remember_clientdata(t, wrap_class); int use_director = Swig_directorclass(n); @@ -1047,7 +1048,6 @@ public: Delete(base_class); Delete(base_class_names); - Delete(smart); Delete(t); Delete(s_members_tab); s_members_tab = 0; diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 56e888f8a..905a0263a 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4365,12 +4365,14 @@ public: Printf(clientdata, "&%s_clientdata", templ); SwigType_remember_mangleddata(pmname, clientdata); - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); if (smart) { - SwigType_add_pointer(smart); - String *smart_pmname = SwigType_manglestr(smart); + SwigType *psmart = Copy(smart); + SwigType_add_pointer(psmart); + String *smart_pmname = SwigType_manglestr(psmart); SwigType_remember_mangleddata(smart_pmname, clientdata); Delete(smart_pmname); + Delete(psmart); } String *clientdata_klass = NewString("0"); @@ -4395,7 +4397,6 @@ public: Printv(f_init, " d = md;\n", NIL); Delete(clientdata); - Delete(smart); Delete(sname); Delete(rname); Delete(mname); @@ -4573,7 +4574,7 @@ public: if (shadow) { /* Generate a class registration function */ // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers) - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); SwigType *ct = Copy(smart ? smart : real_classname); SwigType_add_pointer(ct); SwigType *realct = Copy(real_classname); @@ -4595,7 +4596,6 @@ public: add_method(cname, cname, 0, 0, 1, 1, 1); Delete(cname); } - Delete(smart); Delete(ct); Delete(realct); if (!have_constructor) { diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index cb7d79fc9..f6facbb55 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -1809,7 +1809,7 @@ public: Wrapper_add_local(f, "classname", classname); } if (action) { - SwigType *smart = Swig_cparse_smartptr(pn); + SwigType *smart = Getattr(pn, "smart"); String *result_name = NewStringf("%s%s", smart ? "smart" : "", Swig_cresult_name()); if (smart) { String *result_var = NewStringf("%s *%s = 0", SwigType_namestr(smart), result_name); @@ -1821,7 +1821,6 @@ public: Printf(action, "\nSWIG_RubyAddTracking(%s, self);", result_name); } Delete(result_name); - Delete(smart); } } @@ -1888,16 +1887,17 @@ public: /* Extra code needed for new and initialize methods */ if (current == CONSTRUCTOR_ALLOCATE) { Node *pn = Swig_methodclass(n); - SwigType *smart = Swig_cparse_smartptr(pn); - if (smart) - SwigType_add_pointer(smart); - String *classtype = smart ? smart : t; + SwigType *smart = Getattr(pn, "smart"); + SwigType *psmart = smart ? Copy(smart) : 0; + if (psmart) + SwigType_add_pointer(psmart); + String *classtype = psmart ? psmart : t; need_result = 1; Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(classtype))); Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n"); Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n"); Printf(f->code, "#endif\n"); - Delete(smart); + Delete(psmart); } else if (current == CONSTRUCTOR_INITIALIZE) { need_result = 1; } @@ -2399,12 +2399,13 @@ public: SwigType *btype = NewString(basename); SwigType_add_pointer(btype); SwigType_remember(btype); - SwigType *smart = Swig_cparse_smartptr(base.item); - if (smart) { - SwigType_add_pointer(smart); - SwigType_remember(smart); + SwigType *smart = Getattr(base.item, "smart"); + SwigType *psmart = smart ? Copy(psmart) : 0; + if (psmart) { + SwigType_add_pointer(psmart); + SwigType_remember(psmart); } - String *bmangle = SwigType_manglestr(smart ? smart : btype); + String *bmangle = SwigType_manglestr(psmart ? psmart : btype); if (multipleInheritance) { Insert(bmangle, 0, "((swig_class *) SWIGTYPE"); Append(bmangle, "->clientdata)->mImpl"); @@ -2415,7 +2416,7 @@ public: Replaceall(klass->init, "$super", bmangle); } Delete(bmangle); - Delete(smart); + Delete(psmart); Delete(btype); } base = Next(base); @@ -2516,15 +2517,15 @@ public: SwigType *tt = NewString(name); SwigType_add_pointer(tt); SwigType_remember(tt); - SwigType *smart = Swig_cparse_smartptr(n); - if (smart) { - SwigType_add_pointer(smart); - SwigType_remember(smart); + SwigType *psmart = Getattr(n, "smart"); + if (psmart) { + SwigType_add_pointer(psmart); + SwigType_remember(psmart); } - String *tm = SwigType_manglestr(smart ? smart : tt); + String *tm = SwigType_manglestr(psmart ? psmart : tt); Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &SwigClass%s);\n", tm, valid_name); Delete(tm); - Delete(smart); + Delete(psmart); Delete(tt); Delete(valid_name); diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index fa89a6363..a053f36f0 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -421,7 +421,6 @@ 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); diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 74171f355..c28226044 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -253,20 +253,18 @@ class TypePass:private Dispatcher { int len = Len(ilist); int i; for (i = 0; i < len; i++) { - Node *n = Getitem(ilist, i); - SwigType *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 = Swig_smartptr_upcast(smart, clsname, bname); + 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); @@ -275,17 +273,15 @@ class TypePass:private Dispatcher { /* 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"))); } } @@ -503,6 +499,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))) { diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx index 2ae1afa61..2d956c4c8 100644 --- a/Source/Modules/utils.cxx +++ b/Source/Modules/utils.cxx @@ -122,67 +122,6 @@ 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" { diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index b76203454..3294bdf77 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -69,8 +69,6 @@ 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) {