diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 71afc0287..4be80dd46 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -464,37 +464,56 @@ class Allocate : public Dispatcher { return methods; } - void mark_exception_classes(Node *n) { - ParmList *throws = 0; - /* the "catchs" feature take precedence over the original throw list */ - String *sthrows = Getattr(n,"feature:catches"); - if (sthrows) { - throws = Swig_cparse_parms(sthrows); - if (throws) { - Setattr(n,"throws",throws); - Delete(throws); + void mark_exception_classes(ParmList *p) + { + while(p) { + SwigType *ty = Getattr(p,"type"); + SwigType *t = SwigType_typedef_resolve_all(ty); + if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) { + Delete(SwigType_pop(t)); + } + Node *c = Swig_symbol_clookup(t,0); + if (c) { + if (!GetFlag(c,"feature:exceptionclass")) { + SetFlag(c,"feature:exceptionclass"); + } + } + p = nextSibling(p); + Delete(t); + } + } + + + void process_exceptions(Node *n) { + ParmList *catchlist = 0; + /* + the "catchlist" attribute is used to emit the block + + try {$action;} + catch ; + + in emit.cxx + + and is either constructued from the "feature:catches" feature + or copied from the node "throws" list. + */ + String *scatchlist = Getattr(n,"feature:catches"); + if (scatchlist) { + catchlist = Swig_cparse_parms(scatchlist); + if (catchlist) { + Setattr(n,"catchlist",catchlist); + mark_exception_classes(catchlist); + Delete(catchlist); } } - if (!throws) { - throws = Getattr(n,"throws"); - } + ParmList *throws = Getattr(n,"throws"); if (throws) { - ParmList *p = throws; - while(p) { - SwigType *ty = Getattr(p,"type"); - SwigType *t = SwigType_typedef_resolve_all(ty); - if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) { - Delete(SwigType_pop(t)); - } - Node *c = Swig_symbol_clookup(t,0); - if (c) { - if (!GetFlag(c,"feature:exceptionclass")) { - SetFlag(c,"feature:exceptionclass"); - } - } - p = nextSibling(p); - Delete(t); + /* if there is no an explicit catchlist, + we catch everything in the throwlist */ + if (!catchlist) { + Setattr(n,"catchlist",throws); } + mark_exception_classes(throws); } } @@ -719,7 +738,7 @@ public: Node *c = 0; for (c = firstChild(n); c; c = nextSibling(c)) { if (Strcmp(nodeType(c),"cdecl") == 0) { - mark_exception_classes(c); + process_exceptions(c); if (inclass) class_member_is_defined_in_bases(c, inclass); @@ -731,7 +750,7 @@ public: virtual int cDeclaration(Node *n) { - mark_exception_classes(n); + process_exceptions(n); if (inclass) { /* check whether the member node n is defined in class node in class's bases */ @@ -815,7 +834,7 @@ public: if (!inclass) return SWIG_OK; Parm *parms = Getattr(n,"parms"); - mark_exception_classes(n); + process_exceptions(n); if (!extendmode) { if (!ParmList_numrequired(parms)) { /* Class does define a default constructor */ diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx index 2720d3be4..c97e434c0 100644 --- a/Source/Modules/emit.cxx +++ b/Source/Modules/emit.cxx @@ -345,7 +345,7 @@ void emit_action(Node *n, Wrapper *f) { String *action; String *wrap; SwigType *rt; - ParmList *throws = Getattr(n,"throws"); + ParmList *catchlist = Getattr(n,"catchlist"); /* Look for fragments */ { @@ -421,16 +421,16 @@ void emit_action(Node *n, Wrapper *f) { /* If we are in C++ mode and there is an exception specification. We're going to enclose the block in a try block */ - if (throws) { + if (catchlist) { Printf(eaction,"try {\n"); } Printv(eaction, action, NIL); - if (throws) { + if (catchlist) { int unknown_catch = 0; Printf(eaction,"}\n"); - for (Parm *ep = throws; ep; ep = nextSibling(ep)) { + for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) { String *em = Swig_typemap_lookup_new("throws",ep,"_e",0); if (em) { SwigType *et = Getattr(ep,"type");