diff --git a/Examples/test-suite/exception_order.i b/Examples/test-suite/exception_order.i index dd0f8c813..35c56adb4 100644 --- a/Examples/test-suite/exception_order.i +++ b/Examples/test-suite/exception_order.i @@ -15,7 +15,7 @@ } } -%throws(E1,E2) A::barfoo(int i); +%throws(E1,E2*,ET,ET) A::barfoo(int i); %inline %{ @@ -31,6 +31,11 @@ { }; + template + struct ET + { + }; + struct A { /* caught by the user's throw definition */ @@ -58,10 +63,18 @@ { if (i == 1) { throw E1(); - } else { - throw E2(); + } else if (i == 2) { + static E2 *ep = new E2(); + throw ep; + } else if (i == 3) { + throw ET(); + } else { + throw ET(); } return 0; } }; %} + +%template(ET_i) ET; +%template(ET_d) ET; diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h index cf52c56a1..5325297f9 100644 --- a/Source/CParse/cparse.h +++ b/Source/CParse/cparse.h @@ -51,6 +51,7 @@ extern int SWIG_cparse_template_reduce(int treduce); extern void Swig_cparse_replace_descriptor(String *s); extern void cparse_normalize_void(Node *); extern Parm *Swig_cparse_parm(String *s); +extern ParmList *Swig_cparse_parms(String *s); /* templ.c */ diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index a04f645eb..b05df1a69 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1344,7 +1344,7 @@ static void default_arguments(Node *n) { %token TEMPLATE %token OPERATOR %token COPERATOR -%token PARSETYPE PARSEPARM +%token PARSETYPE PARSEPARM PARSEPARMS %left CAST %left LOR @@ -1446,6 +1446,12 @@ program : interface { | PARSEPARM error { top = 0; } + | PARSEPARMS LPAREN parms RPAREN SEMI { + top = $3; + } + | PARSEPARMS error SEMI { + top = 0; + } ; interface : interface declaration { @@ -5744,6 +5750,23 @@ Parm *Swig_cparse_parm(String *s) { } +ParmList *Swig_cparse_parms(String *s) { + String *ns; + char *cs = Char(s); + if (cs && cs[0] != '(') { + ns = NewStringf("(%s);",s); + } else { + ns = NewStringf("%s;",s); + } + Seek(ns,0,SEEK_SET); + scanner_file(ns); + top = 0; + scanner_next_token(PARSEPARMS); + yyparse(); + /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ + return top; +} + diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 48a5ba322..1394b7adc 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -19,6 +19,7 @@ char cvsroot_allocate_cxx[] = "$Header$"; #include "swigmod.h" +#include "cparse.h" static int virtual_elimination_mode = 0; /* set to 0 on default */ @@ -463,21 +464,34 @@ class Allocate : public Dispatcher { return methods; } - 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"); + void mark_exception_classes(Node *n) { + ParmList *throws = Getattr(n,"throws"); + if (!throws) { + String *sthrows = Getattr(n,"feature:throws"); + if (sthrows) { + throws = Swig_cparse_parms(sthrows); + if (throws) { + Setattr(n,"throws",throws); } } - p = nextSibling(p); - Delete(t); + } + 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); + } } } @@ -702,7 +716,7 @@ public: Node *c = 0; for (c = firstChild(n); c; c = nextSibling(c)) { if (Strcmp(nodeType(c),"cdecl") == 0) { - mark_exception_classes(Getattr(c,"throws")); + mark_exception_classes(c); if (inclass) class_member_is_defined_in_bases(c, inclass); @@ -714,7 +728,7 @@ public: virtual int cDeclaration(Node *n) { - mark_exception_classes(Getattr(n,"throws")); + mark_exception_classes(n); if (inclass) { /* check whether the member node n is defined in class node in class's bases */ @@ -798,7 +812,7 @@ public: if (!inclass) return SWIG_OK; Parm *parms = Getattr(n,"parms"); - mark_exception_classes(Getattr(n,"throws")); + mark_exception_classes(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 015a6bb7c..c65c4d657 100644 --- a/Source/Modules/emit.cxx +++ b/Source/Modules/emit.cxx @@ -346,18 +346,6 @@ void emit_action(Node *n, Wrapper *f) { String *wrap; SwigType *rt; ParmList *throws = Getattr(n,"throws"); - if (!throws) { - String *tmp = 0; - String *sthrows = Getattr(n,"feature:throws"); - if (sthrows) { - char *cthrows = Char(sthrows); - if (cthrows && cthrows[0] != '(') { - sthrows = tmp = NewStringf("(%s)",sthrows); - } - throws = SwigType_function_parms(sthrows); - if (tmp) Delete (tmp); - } - } /* Look for fragments */ {