Parameter name expansion fix for template functions.

Fix regression in 4.0.0 where a template function containing a parameter
with the same name as the function name led to the parameter name used in the
target language being incorrectly modified.

Closes #1602
This commit is contained in:
William S Fulton 2019-08-01 19:46:16 +01:00
parent 0d76eb3b56
commit 3cc4b21163
3 changed files with 34 additions and 11 deletions

View File

@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.0.1 (in progress)
===========================
2019-08-01: wsfulton
#1602 Fix regression in 4.0.0 where a template function containing a parameter
with the same name as the function name led to the parameter name used in the
target language being incorrectly modified.
2019-07-29: wsfulton
Remove all generated files on error. Previously generated files were not removed,
potentially breaking Makefiles using file dependencies, especially when -Werror

View File

@ -26,3 +26,16 @@ template<typename T> struct X {
%}
%template(Xint) X<int>;
// The function name and parameter name are both 'labels'
%inline %{
template <typename T>
void labels(T labels) {}
void voido(int vooo) {}
%}
// TODO: R has a problem with parameter names clashing with the function name
#if !defined(SWIGR)
%template(ShortLabels) labels<short>;
#endif

View File

@ -26,14 +26,19 @@ void SwigType_template_init() {
}
static void add_parms(ParmList *p, List *patchlist, List *typelist) {
static void add_parms(ParmList *p, List *patchlist, List *typelist, int is_pattern) {
while (p) {
SwigType *ty = Getattr(p, "type");
SwigType *val = Getattr(p, "value");
SwigType *name = Getattr(p, "name");
Append(typelist, ty);
Append(typelist, val);
if (is_pattern) {
/* Typemap patterns are not simple parameter lists.
* Output style ("out", "ret" etc) typemap names can be
* qualified names and so may need template expansion */
SwigType *name = Getattr(p, "name");
Append(typelist, name);
}
Append(patchlist, val);
p = nextSibling(p);
}
@ -108,8 +113,8 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
Append(typelist, Getattr(n, "name"));
}
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
} else if (Equal(nodeType, "class")) {
/* Patch base classes */
@ -175,8 +180,8 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
}
Append(cpatchlist, Getattr(n, "code"));
Append(typelist, Getattr(n, "decl"));
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
} else if (Equal(nodeType, "destructor")) {
/* 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. */
@ -217,10 +222,10 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
Append(cpatchlist, Getattr(n, "code"));
Append(typelist, Getattr(n, "type"));
Append(typelist, Getattr(n, "decl"));
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
add_parms(Getattr(n, "kwargs"), cpatchlist, typelist);
add_parms(Getattr(n, "pattern"), cpatchlist, typelist);
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
add_parms(Getattr(n, "kwargs"), cpatchlist, typelist, 0);
add_parms(Getattr(n, "pattern"), cpatchlist, typelist, 1);
add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
cn = firstChild(n);
while (cn) {
cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);