Fix assertion handling defaultargs

Occurs when using %extend for a template class and the extended methods
contain default arguments.

Closes #611
This commit is contained in:
William S Fulton 2016-05-07 12:33:29 +01:00
commit 15ebf3df03
5 changed files with 87 additions and 7 deletions

View file

@ -145,7 +145,7 @@ static Node *copy_node(Node *n) {
Setattr(nn, key, k.item);
continue;
}
/* defaultargs will be patched back in later */
/* defaultargs will be patched back in later in update_defaultargs() */
if (strcmp(ckey,"defaultargs") == 0) {
Setattr(nn, "needs_defaultargs", "1");
continue;
@ -660,19 +660,26 @@ static void add_symbols_copy(Node *n) {
}
}
/* Add in the "defaultargs" attribute for functions in instantiated templates.
* n should be any instantiated template (class or start of linked list of functions). */
static void update_defaultargs(Node *n) {
if (n) {
Node *firstdefaultargs = n;
update_defaultargs(firstChild(n));
n = nextSibling(n);
/* recursively loop through nodes of all types, but all we really need are the overloaded functions */
while (n) {
update_defaultargs(firstChild(n));
assert(!Getattr(n, "defaultargs"));
if (Getattr(n, "needs_defaultargs")) {
Setattr(n, "defaultargs", firstdefaultargs);
Delattr(n, "needs_defaultargs");
if (!Getattr(n, "defaultargs")) {
if (Getattr(n, "needs_defaultargs")) {
Setattr(n, "defaultargs", firstdefaultargs);
Delattr(n, "needs_defaultargs");
} else {
firstdefaultargs = n;
}
} else {
firstdefaultargs = n;
/* Functions added in with %extend (for specialized template classes) will already have default args patched up */
assert(Getattr(n, "defaultargs") == firstdefaultargs);
}
n = nextSibling(n);
}
@ -2756,7 +2763,11 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
Swig_symbol_setscope(csyms);
}
/* Merge in %extend methods for this class */
/* Merge in %extend methods for this class.
This only merges methods within %extend for a template specialized class such as
template<typename T> class K {}; %extend K<int> { ... }
The copy_node() call above has already added in the generic %extend methods such as
template<typename T> class K {}; %extend K { ... } */
/* !!! This may be broken. We may have to add the
%extend methods at the beginning of the class */