%shared_ptr support improvements for classes in an inheritance chain

Fix %shared_ptr support for private and protected inheritance.
- Remove unnecessary Warning 520: Derived class 'Derived' of 'Base'
  is not similarly marked as a smart pointer
- Do not generate code that attempts to cast up the inheritance chain in the
  type system runtime in such cases as it doesn't compile and can't be used.
Remove unnecessary warning 520 for %shared_ptr when the base class is ignored.
This commit is contained in:
William S Fulton 2015-10-01 22:31:38 +01:00
commit fc2205e64d
3 changed files with 87 additions and 29 deletions

View file

@ -5,6 +5,14 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.8 (in progress) Version 3.0.8 (in progress)
=========================== ===========================
2015-10-01: wsfulton
Fix %shared_ptr support for private and protected inheritance.
- Remove unnecessary Warning 520: Derived class 'Derived' of 'Base'
is not similarly marked as a smart pointer
- Do not generate code that attempts to cast up the inheritance chain in the
type system runtime in such cases as it doesn't compile and can't be used.
Remove unnecessary warning 520 for %shared_ptr when the base class is ignored.
2015-09-26: wsfulton 2015-09-26: wsfulton
[Ruby] Add shared_ptr support [Ruby] Add shared_ptr support

View file

@ -166,3 +166,51 @@ public:
int HiddenPrivateDestructor::DeleteCount = 0; int HiddenPrivateDestructor::DeleteCount = 0;
%} %}
/////////////////////////////////////////////////
// Non-public inheritance and shared_ptr
/////////////////////////////////////////////////
#if defined(SHARED_PTR_WRAPPERS_IMPLEMENTED)
%shared_ptr(Base)
// No %shared_ptr(DerivedPrivate1) to check Warning 520 does not appear
// No %shared_ptr(DerivedProtected1) to check Warning 520 does not appear
%shared_ptr(DerivedPrivate2)
%shared_ptr(DerivedProtected2)
%ignore Base2;
%shared_ptr(DerivedPublic)
#endif
%inline %{
class Base {
public:
virtual int b() = 0;
};
class DerivedProtected1 : protected Base {
public:
virtual int b() { return 20; }
};
class DerivedPrivate1 : private Base {
public:
virtual int b() { return 20; }
};
class DerivedProtected2 : protected Base {
public:
virtual int b() { return 20; }
};
class DerivedPrivate2 : private Base {
public:
virtual int b() { return 20; }
};
class Base2 {
public:
virtual int b2() = 0;
};
class DerivedPublic : public Base2 {
public:
virtual int b2() { return 20; }
};
%}

View file

@ -254,36 +254,38 @@ class TypePass:private Dispatcher {
Node *bclass = n; /* Getattr(n,"class"); */ Node *bclass = n; /* Getattr(n,"class"); */
Hash *scopes = Getattr(bclass, "typescope"); Hash *scopes = Getattr(bclass, "typescope");
SwigType_inherit(clsname, bname, cast, 0); SwigType_inherit(clsname, bname, cast, 0);
String *smartptr = Getattr(first, "feature:smartptr"); if (ispublic && !GetFlag(bclass, "feature:ignore")) {
if (smartptr) { String *smartptr = Getattr(first, "feature:smartptr");
SwigType *smart = Swig_cparse_smartptr(first); if (smartptr) {
if (smart) { SwigType *smart = Swig_cparse_smartptr(first);
/* Record a (fake) inheritance relationship between smart pointer if (smart) {
and smart pointer to base class, so that smart pointer upcasts /* Record a (fake) inheritance relationship between smart pointer
are automatically generated. */ and smart pointer to base class, so that smart pointer upcasts
SwigType *bsmart = Copy(smart); are automatically generated. */
SwigType *rclsname = SwigType_typedef_resolve_all(clsname); SwigType *bsmart = Copy(smart);
SwigType *rbname = SwigType_typedef_resolve_all(bname); SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
Replaceall(bsmart, rclsname, rbname); SwigType *rbname = SwigType_typedef_resolve_all(bname);
Delete(rclsname); Replaceall(bsmart, rclsname, rbname);
Delete(rbname); Delete(rclsname);
String *smartnamestr = SwigType_namestr(smart); Delete(rbname);
String *bsmartnamestr = SwigType_namestr(bsmart); String *smartnamestr = SwigType_namestr(smart);
/* construct casting code */ String *bsmartnamestr = SwigType_namestr(bsmart);
String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr); /* construct casting code */
Delete(bsmartnamestr); String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
Delete(smartnamestr); Delete(bsmartnamestr);
/* setup inheritance relationship between smart pointer templates */ Delete(smartnamestr);
SwigType_inherit(smart, bsmart, 0, convcode); /* setup inheritance relationship between smart pointer templates */
if (!GetFlag(bclass, "feature:smartptr")) SwigType_inherit(smart, bsmart, 0, convcode);
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"))); if (!GetFlag(bclass, "feature:smartptr"))
Delete(convcode); 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(bsmart); Delete(convcode);
Delete(bsmart);
}
Delete(smart);
} else {
if (GetFlag(bclass, "feature:smartptr"))
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")));
} }
Delete(smart);
} else {
if (GetFlag(bclass, "feature:smartptr"))
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")));
} }
if (!importmode) { if (!importmode) {
String *btype = Copy(bname); String *btype = Copy(bname);