mirror of https://github.com/swig/swig
Fix assertion handling upcasting when using %shared_ptr on some templates.
A different approach is taken for supporting casting smart pointers up the inheritance hierarchy. We no longer try to replace the underlying pointer type, provided in the 'feature:smartptr', with the base class type. Such as morphing 'std::shared_ptr<(Derived)>' into 'std::shared_ptr<(Base)>'. Instead, we simply use 'feature:smartptr' from the base class. This is more reliable than trying to pattern match the pointer type in the feature. The base class must of course also have the 'feature:smartptr' set, and this is still checked for as before. The feature is now parsed in one place and stored in the parse tree in the new 'smart' attribute for handling by the target languages. Fix also improves the handling of the type parsed in 'feature:smartptr' in that the type is now normalized and resolved in the scope of the class it is attached to. Closes #2768
This commit is contained in:
parent
d6850a60fa
commit
3be670e8db
|
@ -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.
|
||||
|
|
|
@ -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 <std_shared_ptr.i>
|
||||
|
||||
%{
|
||||
#include <memory>
|
||||
namespace stir {}
|
||||
using namespace stir;
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
namespace stir {
|
||||
// Note: CRTP
|
||||
template <typename Derived, typename Base, typename Parent = Base>
|
||||
class RegisteredParsingObject : public Parent {
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
%shared_ptr(stir::Array<3,float>)
|
||||
%inline %{
|
||||
namespace stir {
|
||||
template <int num_dimensions, typename elemT>
|
||||
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<int num_dimensions, typename elemT>
|
||||
class DiscretisedDensity : public ExamData, public Array<num_dimensions,elemT> {
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
%shared_ptr(stir::DataProcessor<stir::DiscretisedDensity<3,float> >)
|
||||
%shared_ptr(stir::RegisteredParsingObject<
|
||||
stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >,
|
||||
stir::DataProcessor<DiscretisedDensity<3,float> >,
|
||||
stir::DataProcessor<DiscretisedDensity<3,float> > >)
|
||||
%shared_ptr(stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >)
|
||||
|
||||
%inline %{
|
||||
namespace stir {
|
||||
template <typename DataT>
|
||||
class DataProcessor {
|
||||
};
|
||||
|
||||
template <typename DataT>
|
||||
class ChainedDataProcessor : public RegisteredParsingObject< ChainedDataProcessor<DataT>, DataProcessor<DataT>, DataProcessor<DataT> > {
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
// 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<stir::DiscretisedDensity<3,float> >;
|
||||
%template(RPChainedDataProcessor3DFloat) stir::RegisteredParsingObject<
|
||||
stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >,
|
||||
stir::DataProcessor<DiscretisedDensity<3,float> >,
|
||||
stir::DataProcessor<DiscretisedDensity<3,float> > >;
|
||||
%template(ChainedDataProcessor3DFloat) stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >;
|
||||
|
||||
%inline %{
|
||||
void useobject(stir::RegisteredParsingObject<
|
||||
stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >,
|
||||
stir::DataProcessor<DiscretisedDensity<3,float> >,
|
||||
stir::DataProcessor<DiscretisedDensity<3,float> > >) {
|
||||
}
|
||||
%}
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 {};
|
|
@ -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.
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,7 +1771,7 @@ public:
|
|||
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
|
||||
|
||||
if (smart) {
|
||||
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
|
||||
if (bsmart) {
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
|
||||
|
@ -1781,7 +1782,7 @@ public:
|
|||
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
}
|
||||
} 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")) {
|
||||
|
||||
|
|
|
@ -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,7 +3419,7 @@ private:
|
|||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
|
||||
if (smart) {
|
||||
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
|
||||
if (bsmart) {
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
|
||||
|
@ -3430,7 +3432,7 @@ private:
|
|||
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
|
|
|
@ -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,14 +1841,14 @@ 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);
|
||||
if (bsmart) {
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
|
||||
|
@ -1864,7 +1865,7 @@ public:
|
|||
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
}
|
||||
} 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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
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 = Swig_smartptr_upcast(smart, clsname, bname);
|
||||
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);
|
||||
}
|
||||
Delete(smart);
|
||||
} else {
|
||||
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")));
|
||||
}
|
||||
} else {
|
||||
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))) {
|
||||
|
|
|
@ -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" {
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue