diff --git a/Examples/test-suite/director_exception.i b/Examples/test-suite/director_exception.i index b130eacdb..7211140ff 100644 --- a/Examples/test-suite/director_exception.i +++ b/Examples/test-suite/director_exception.i @@ -92,12 +92,19 @@ Foo *launder(Foo *f); { }; - class Bar + class Base + { + public: + virtual ~Base() throw () {} + }; + + + class Bar : public Base { public: - virtual ~Bar(){} virtual std::string ping() throw (Exception1, Exception2&) { return "Bar::ping()"; } virtual std::string pong() throw (Unknown1, int, Unknown2&) { return "Bar::pong();" + ping(); } + virtual std::string pang() throw () { return "Bar::pang()"; } }; %} diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 11afa8f8d..7b99242d6 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1524,8 +1524,9 @@ int Language::unrollVirtualMethods(Node *n, /* we only need to check the virtual members */ if (!checkAttribute(ni, "storage", "virtual")) continue; nodeType = Getattr(ni, "nodeType"); - /* we need to add only the methods(cdecl), no destructors */ - if ((Cmp(nodeType, "cdecl") == 0)) { + /* we need to add methods(cdecl) and destructor (to check for throw decl) */ + int is_destructor = (Cmp(nodeType, "destructor") == 0); + if ((Cmp(nodeType, "cdecl") == 0)|| is_destructor) { decl = Getattr(ni, "decl"); /* extra check for function type and proper access */ int need_nopublic = dirprot_mode() && @@ -1534,9 +1535,10 @@ int Language::unrollVirtualMethods(Node *n, if (SwigType_isfunction(decl) && (is_public(ni) || need_nopublic)) { - String *name = Getattr(ni, "name"); + String *name = Getattr(ni, "sym:name"); String *local_decl = SwigType_typedef_resolve_all(decl); - Node *method_id = NewStringf("%s|%s", name, local_decl); + + Node *method_id = is_destructor ? NewStringf("~destructor") : NewStringf("%s|%s", name, local_decl); /* Make sure that the new method overwrites the existing: */ Hash *exists_item = Getattr(vm, method_id); if (exists_item) { @@ -1558,8 +1560,9 @@ int Language::unrollVirtualMethods(Node *n, Delete(method_id); Delete(local_decl); } - } else if (Cmp(nodeType, "destructor") == 0) { - virtual_destructor = 1; + if (is_destructor) { + virtual_destructor = 1; + } } } @@ -1701,11 +1704,18 @@ int Language::classDirectorMethods(Node *n) { String *fqname = Getattr(item, "fqName"); if (!Cmp(Getattr(method, "feature:nodirector"), "1")) continue; - - if (classDirectorMethod(method, n, fqname) == SWIG_OK) { - Setattr(item, "director", "1"); + + String *type = Getattr(method, "nodeType"); + if (!Cmp(type, "destructor")) { + classDirectorDestructor(method); + } + else { + if (classDirectorMethod(method, n, fqname) == SWIG_OK) { + Setattr(item, "director", "1"); + } } } + return SWIG_OK; } @@ -1718,6 +1728,20 @@ int Language::classDirectorInit(Node *n) { return SWIG_OK; } +/* ---------------------------------------------------------------------- + * Language::classDirectorDestructor() + * ---------------------------------------------------------------------- */ + +int Language::classDirectorDestructor(Node *n) { + if (Getattr(n,"throw")) { + File *f_directors_h = Swig_filebyname("director_h"); + String *classname= Swig_class_name(getCurrentClass()); + Printf(f_directors_h, " virtual ~SwigDirector_%s() throw () {}\n", classname); + Delete(classname); + } + return SWIG_OK; +} + /* ---------------------------------------------------------------------- * Language::classDirectorEnd() * ---------------------------------------------------------------------- */ @@ -1951,6 +1975,8 @@ int Language::classHandler(Node *n) { for (k = First(vtable); k.key; k = Next(k)) { item = k.item; Node *method = Getattr(item, "methodNode"); + SwigType *type = Getattr(method,"nodeType"); + if (Strcmp(type,"cdecl") !=0 ) continue; String* methodname = Getattr(method,"sym:name"); String* wrapname = NewStringf("%s_%s", symname,methodname); if (!Getattr(symbols,wrapname) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 696e3405d..3b3ce9484 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -504,7 +504,7 @@ public: int functionHandler(Node *n) { - if (checkAttribute(n,"feature:python:callback","1")) { + if (Getattr(n,"feature:python:callback")) { Setattr(n,"feature:callback","%s_cb_ptr"); autodoc_l dlevel = autodoc_level(Getattr(n, "feature:autodoc")); if (dlevel != NO_AUTODOC && dlevel > TYPES_AUTODOC) { @@ -523,7 +523,7 @@ public: * ------------------------------------------------------------ */ void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) { - if (checkAttribute(n,"feature:python:callback","1") || ! have_addtofunc(n) ) { + if (Getattr(n,"feature:python:callback") || ! have_addtofunc(n) ) { /* If there is no addtofunc directive then just assign from the extension module */ Printv(f_dest, "\n", name, " = ", module, ".", name, "\n", NIL); } else { @@ -776,7 +776,7 @@ public: String* make_autodocParmList(Node* n, bool showTypes) { String* doc = NewString(""); String* pdocs = Copy(Getattr(n,"feature:pdocs")); - ParmList* plist = Getattr(n,"parms"); + ParmList* plist = CopyParmList(Getattr(n,"parms")); Parm* p; Parm* pnext; Node* lookup; @@ -854,6 +854,7 @@ public: } } if (pdocs) Setattr(n,"feature:pdocs", pdocs); + Delete(plist); return doc; } @@ -1679,14 +1680,14 @@ public: // Get any exception classes in the throws typemap ParmList *throw_parm_list = 0; - if ((throw_parm_list = Getattr(n,"throws"))) { + if ((throw_parm_list = Getattr(n,"throws")) || Getattr(n,"throw")) { Parm *p; int gencomma = 0; Append(w->def, " throw("); Append(declaration, " throw("); - Swig_typemap_attach_parms("throws", throw_parm_list, 0); + if (throw_parm_list) Swig_typemap_attach_parms("throws", throw_parm_list, 0); for (p = throw_parm_list; p; p=nextSibling(p)) { if ((tm = Getattr(p,"tmap:throws"))) { if (gencomma++) { @@ -2332,18 +2333,20 @@ public: if (!have_repr) { /* Supply a repr method for this class */ - if (new_repr) { - Printv(f_shadow_file, + String *rname = SwigType_namestr(real_classname); + if (new_repr) { + Printv(f_shadow_file, tab4, "def __repr__(self):\n", - tab8, "return \"<%s.%s; proxy of ", CPlusPlus ? "C++ " : "C ", real_classname," instance at %s>\" % (self.__class__.__module__, self.__class__.__name__, self.this,)\n", + tab8, "return \"<%s.%s; proxy of ", CPlusPlus ? "C++ " : "C ", rname," instance at %s>\" % (self.__class__.__module__, self.__class__.__name__, self.this,)\n", NIL); - } - else { - Printv(f_shadow_file, + } + else { + Printv(f_shadow_file, tab4, "def __repr__(self):\n", - tab8, "return \"\" % (self.this,)\n", + tab8, "return \"\" % (self.this,)\n", NIL); - } + } + Delete(rname); } @@ -2441,7 +2444,7 @@ public: String *symname = Getattr(n,"sym:name"); Language::staticmemberfunctionHandler(n); if (shadow) { - if ( !classic && (have_pythonprepend(n) || have_pythonappend(n) || have_docstring(n)) ) { + if ( !classic && !Getattr(n,"feature:python:callback") && have_addtofunc(n)) { int kw = (check_kwargs(n) && !Getattr(n,"sym:overloaded")) ? 1 : 0; Printv(f_shadow, tab4, "def ", symname, "(*args", (kw ? ", **kwargs" : ""), "):\n", NIL); if ( have_docstring(n) ) diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index e179bb58b..05c3bc15b 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -205,6 +205,7 @@ public: virtual int classDirectorDefaultConstructor(Node *n); virtual int classDirectorMethod(Node *n, Node *parent, String *super); virtual int classDirectorConstructors(Node *n); + virtual int classDirectorDestructor(Node *n); virtual int classDirectorMethods(Node *n); virtual int classDirectorDisown(Node *n);