diff --git a/SWIG/Examples/test-suite/python/smart_pointer_extend_runme.py b/SWIG/Examples/test-suite/python/smart_pointer_extend_runme.py index 0b2ff0f26..0b62b9865 100644 --- a/SWIG/Examples/test-suite/python/smart_pointer_extend_runme.py +++ b/SWIG/Examples/test-suite/python/smart_pointer_extend_runme.py @@ -11,9 +11,14 @@ b = CBase() d = CDerived() p = CPtr() +if b.bar() != p.bar(): + raise RuntimeError if d.foo() != p.foo(): raise RuntimeError +if b.hello() != p.hello(): + raise RuntimeError + diff --git a/SWIG/Examples/test-suite/python/smart_pointer_member_runme.py b/SWIG/Examples/test-suite/python/smart_pointer_member_runme.py index 49b3ef0f7..70e655652 100644 --- a/SWIG/Examples/test-suite/python/smart_pointer_member_runme.py +++ b/SWIG/Examples/test-suite/python/smart_pointer_member_runme.py @@ -19,3 +19,12 @@ if b.x != f.x: if b.z != f.z: raise RuntimeError + +if Foo.z == Bar.z: + raise RuntimeError + + + + + + diff --git a/SWIG/Examples/test-suite/smart_pointer_extend.i b/SWIG/Examples/test-suite/smart_pointer_extend.i index 402aecac8..61eeaebfd 100644 --- a/SWIG/Examples/test-suite/smart_pointer_extend.i +++ b/SWIG/Examples/test-suite/smart_pointer_extend.i @@ -1,30 +1,51 @@ %module smart_pointer_extend %inline %{ + namespace hi + { + struct CBase + { + static int hello() + { + return 1; + } + }; -class CBase -{ -}; + class CDerived : public CBase + { + }; -class CDerived : public CBase -{ -}; + class CPtr + { + public: + CDerived* operator->(void) {return 0;}; + }; -class CPtr -{ -public: - CDerived* operator->(void) {return 0;}; -}; + int get_hello(CPtr ptr) + { + return ptr->hello(); + } + class CPtrConst + { + public: + CDerived* operator->(void) const {return 0;}; + }; + + } + %} -%extend CBase { +%extend hi::CBase { + int foo(void) {return 1;}; + int bar(void) {return 2;}; + int boo(int i) {return i;}; +} + +%extend hi::CDerived { int foo(void) {return 1;}; } -%extend CDerived { - int foo(void) {return 2;}; -} %extend Foo diff --git a/SWIG/Examples/test-suite/smart_pointer_member.i b/SWIG/Examples/test-suite/smart_pointer_member.i index 4c20b9b9e..572893bfd 100644 --- a/SWIG/Examples/test-suite/smart_pointer_member.i +++ b/SWIG/Examples/test-suite/smart_pointer_member.i @@ -9,6 +9,9 @@ int x[4]; int y; static const int z; + + static int boo() { return 0;} + }; class Bar { @@ -18,6 +21,17 @@ Foo *operator->() { return f; } + + static int bua() { return 0;} + }; + + class CBar { + Foo *f; + public: + CBar(Foo *f) : f(f) { } + Foo *operator->() const { + return f; + } }; int get_y(Bar *b) diff --git a/SWIG/Source/Modules/allocate.cxx b/SWIG/Source/Modules/allocate.cxx index c3061dee5..7b2001b73 100644 --- a/SWIG/Source/Modules/allocate.cxx +++ b/SWIG/Source/Modules/allocate.cxx @@ -250,7 +250,8 @@ class Allocate : public Dispatcher { /* Grab methods used by smart pointers */ - List *smart_pointer_methods(Node *cls, List *methods, int isconst) { + List *smart_pointer_methods(Node *cls, List *methods, int isconst, + String *classname=0) { if (!methods) { methods = NewList(); } @@ -266,7 +267,7 @@ class Allocate : public Dispatcher { continue; } if (!isconst && (Strcmp(nodeType(c),"extend") == 0)) { - methods = smart_pointer_methods(c, methods, isconst); + methods = smart_pointer_methods(c, methods, isconst, Getattr(cls,"name")); } else if (Strcmp(nodeType(c),"cdecl") == 0) { if (!Getattr(c,"feature:ignore")) { String *storage = Getattr(c,"storage"); @@ -296,23 +297,30 @@ class Allocate : public Dispatcher { if (!match) { Node *cc = c; while (cc) { + Node *cp = cc; + if (classname) { + Setattr(cp,"classname",classname); + } + Setattr(cp,"allocate:smartpointeraccess","1"); /* If constant, we have to be careful */ if (isconst) { - SwigType *decl = Getattr(cc,"decl"); + SwigType *decl = Getattr(cp,"decl"); if (decl) { if (SwigType_isfunction(decl)) { /* If method, we only add if it's a const method */ if (SwigType_isconst(decl)) { - Append(methods,cc); + Append(methods,cp); } } else { - Append(methods,cc); + Append(methods,cp); } } else { - Append(methods,cc); + Setattr(cp,"feature:immutable","1"); + Append(methods,cp); } } else { - Append(methods,cc); + Append(methods,cp); } + Delete(cp); cc = Getattr(cc,"sym:nextSibling"); } } diff --git a/SWIG/Source/Modules/lang.cxx b/SWIG/Source/Modules/lang.cxx index d1e2580f2..d5e357087 100644 --- a/SWIG/Source/Modules/lang.cxx +++ b/SWIG/Source/Modules/lang.cxx @@ -899,7 +899,8 @@ Language::functionHandler(Node *n) { globalfunctionHandler(n); } else { String *storage = Getattr(n,"storage"); - if (Cmp(storage,"static") == 0) { + if (Cmp(storage,"static") == 0 && + !(SmartPointer && Getattr(n,"allocate:smartpointeraccess"))) { staticmemberfunctionHandler(n); } else if (Cmp(storage,"friend") == 0) { globalfunctionHandler(n); @@ -1049,7 +1050,9 @@ Language::memberfunctionHandler(Node *n) { String *fname = Swig_name_member(ClassPrefix, symname); if (Extend && SmartPointer) { - Setattr(n,"classname",Getattr(CurrentClass,"allocate:smartpointerbase")); + if (!Getattr(n,"classname")) { + Setattr(n,"classname",Getattr(CurrentClass,"allocate:smartpointerbase")); + } } /* Transformation */ Swig_MethodToFunction(n,ClassType, Getattr(n,"template") ? 0 : Extend | SmartPointer); @@ -1133,14 +1136,15 @@ Language::variableHandler(Node *n) { String *storage = Getattr(n,"storage"); Swig_save("variableHandler",n,"feature:immutable",NIL); if (SmartPointer) { + /* If a smart-pointer and it's a constant access, we have to set immutable */ if (Getattr(CurrentClass,"allocate:smartpointerconst")) { Setattr(n,"feature:immutable","1"); } } - if ((Cmp(storage,"static") == 0)) { + if ((Cmp(storage,"static") == 0) + && !(SmartPointer && Getattr(n,"allocate:smartpointeraccess"))) { staticmembervariableHandler(n); } else { - /* If a smart-pointer and it's a constant access, we have to set immutable */ membervariableHandler(n); } Swig_restore(n);