diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 3cc58de1b..93c5dec2c 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -49,7 +49,7 @@ void Swig_cparse_debug_templates(int x) { * template parameters * ----------------------------------------------------------------------------- */ -static void cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) { +static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) { static int expanded = 0; String *nodeType; if (!n) @@ -63,7 +63,7 @@ static void cparse_template_expand(Node *n, String *tname, String *rname, String if (!expanded) { expanded = 1; set_nodeType(n, Getattr(n, "templatetype")); - cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist); + cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); expanded = 0; return; } else { @@ -71,7 +71,7 @@ static void cparse_template_expand(Node *n, String *tname, String *rname, String /* Member templates */ set_nodeType(n, Getattr(n, "templatetype")); - cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist); + cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); set_nodeType(n, "template"); return; } @@ -130,7 +130,7 @@ static void cparse_template_expand(Node *n, String *tname, String *rname, String { Node *cn = firstChild(n); while (cn) { - cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); + cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); cn = nextSibling(cn); } } @@ -176,25 +176,30 @@ static void cparse_template_expand(Node *n, String *tname, String *rname, String add_parms(Getattr(n, "parms"), cpatchlist, typelist); add_parms(Getattr(n, "throws"), cpatchlist, typelist); } else if (Equal(nodeType, "destructor")) { - String *name = Getattr(n, "name"); - if (name) { - if (strchr(Char(name), '<')) - Append(patchlist, Getattr(n, "name")); - else - Append(name, templateargs); - } - name = Getattr(n, "sym:name"); - if (name) { - if (strchr(Char(name), '<')) { - String *sn = Copy(tname); - Setattr(n, "sym:name", sn); - Delete(sn); - } else { - Replace(name, tname, rname, DOH_REPLACE_ANY); + /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root + * template node, with the special exception for %extend which adds its methods under an intermediate node. */ + Node* parent = parentNode(n); + if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) { + String *name = Getattr(n, "name"); + if (name) { + if (strchr(Char(name), '<')) + Append(patchlist, Getattr(n, "name")); + else + Append(name, templateargs); } + name = Getattr(n, "sym:name"); + if (name) { + if (strchr(Char(name), '<')) { + String *sn = Copy(tname); + Setattr(n, "sym:name", sn); + Delete(sn); + } else { + Replace(name, tname, rname, DOH_REPLACE_ANY); + } + } + /* Setattr(n,"sym:name",name); */ + Append(cpatchlist, Getattr(n, "code")); } - /* Setattr(n,"sym:name",name); */ - Append(cpatchlist, Getattr(n, "code")); } else if (Equal(nodeType, "using")) { String *uname = Getattr(n, "uname"); if (uname && strchr(Char(uname), '<')) { @@ -216,7 +221,7 @@ static void cparse_template_expand(Node *n, String *tname, String *rname, String add_parms(Getattr(n, "throws"), cpatchlist, typelist); cn = firstChild(n); while (cn) { - cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); + cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); cn = nextSibling(cn); } } @@ -304,7 +309,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab /* Printf(stdout,"targs = '%s'\n", templateargs); Printf(stdout,"rname = '%s'\n", rname); Printf(stdout,"tname = '%s'\n", tname); */ - cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist); + cparse_template_expand(n, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); /* Set the name */ {