mirror of https://github.com/swig/swig
Fix using declaration in derived class bugs
Problem when all the base class's overloaded methods were overridden in the derived class - fixes "multiply defined" errors. Linked lists of the overloaded methods were not set up correctly when handling the using declaration. Closes #2244
This commit is contained in:
parent
a343b7e254
commit
469f694ae6
|
@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.1.0 (in progress)
|
||||
===========================
|
||||
|
||||
2022-03-24: wsfulton
|
||||
#2244 Fix using declaration in derived class bugs when all the base
|
||||
class's overloaded methods were overridden in the derived class -
|
||||
fixes "multiply defined" errors.
|
||||
|
||||
2022-03-23: wsfulton
|
||||
[Python] #1779 The -py3 option is deprecated and now has no effect on the
|
||||
code generated. Use of this option results in a deprecated warning.
|
||||
|
|
|
@ -29,3 +29,57 @@ typedef not working yet
|
|||
*/
|
||||
}
|
||||
%}
|
||||
|
||||
|
||||
%inline %{
|
||||
// Test using declaration in various positions before and after overloaded methods
|
||||
// Testing where the derived class overrides all the base class methods (and more)
|
||||
namespace Bites
|
||||
{
|
||||
struct Base
|
||||
{
|
||||
virtual ~Base() {}
|
||||
virtual void grab() {}
|
||||
virtual void grab(int i) {}
|
||||
};
|
||||
struct Derived1 : public Base
|
||||
{
|
||||
using Base::grab;
|
||||
virtual void grab() {}
|
||||
virtual void grab(int i) {}
|
||||
};
|
||||
struct Derived2 : public Base
|
||||
{
|
||||
using Base::grab;
|
||||
virtual void grab() {}
|
||||
virtual void grab(int i) {}
|
||||
virtual void grab(int i, double d) {}
|
||||
};
|
||||
struct Derived3 : public Base
|
||||
{
|
||||
virtual void grab() {}
|
||||
using Base::grab;
|
||||
virtual void grab(int i) {}
|
||||
};
|
||||
struct Derived4 : public Base
|
||||
{
|
||||
virtual void grab() {}
|
||||
using Base::grab;
|
||||
virtual void grab(int i) {}
|
||||
virtual void grab(int i, double d) {}
|
||||
};
|
||||
struct Derived5 : public Base
|
||||
{
|
||||
virtual void grab() {}
|
||||
virtual void grab(int i) {}
|
||||
using Base::grab;
|
||||
};
|
||||
struct Derived6 : public Base
|
||||
{
|
||||
virtual void grab() {}
|
||||
virtual void grab(int i) {}
|
||||
virtual void grab(int i, double d) {}
|
||||
using Base::grab;
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -1159,14 +1159,30 @@ class TypePass:private Dispatcher {
|
|||
* which is hacked. */
|
||||
if (Getattr(n, "sym:overloaded")) {
|
||||
int cnt = 0;
|
||||
Node *ps = Getattr(n, "sym:previousSibling");
|
||||
Node *ns = Getattr(n, "sym:nextSibling");
|
||||
Node *fc = firstChild(n);
|
||||
Node *firstoverloaded = Getattr(n, "sym:overloaded");
|
||||
#ifdef DEBUG_OVERLOADED
|
||||
Node *debugnode = n;
|
||||
show_overloaded(n);
|
||||
show_overloaded(firstoverloaded);
|
||||
#endif
|
||||
if (!firstChild(n)) {
|
||||
|
||||
if (firstoverloaded == n) {
|
||||
// This 'using' node we are cutting out was the first node in the overloaded list.
|
||||
// Change the first node in the list
|
||||
Delattr(firstoverloaded, "sym:overloaded");
|
||||
firstoverloaded = fc ? fc : ns;
|
||||
|
||||
// Correct all the sibling overloaded methods (before adding in new methods)
|
||||
Node *nnn = ns;
|
||||
while (nnn) {
|
||||
Setattr(nnn, "sym:overloaded", firstoverloaded);
|
||||
nnn = Getattr(nnn, "sym:nextSibling");
|
||||
}
|
||||
}
|
||||
|
||||
if (!fc) {
|
||||
// Remove from overloaded list ('using' node does not actually end up adding in any methods)
|
||||
Node *ps = Getattr(n, "sym:previousSibling");
|
||||
Node *ns = Getattr(n, "sym:nextSibling");
|
||||
if (ps) {
|
||||
Setattr(ps, "sym:nextSibling", ns);
|
||||
}
|
||||
|
@ -1174,24 +1190,8 @@ class TypePass:private Dispatcher {
|
|||
Setattr(ns, "sym:previousSibling", ps);
|
||||
}
|
||||
} else {
|
||||
// The 'using' node results in methods being added in - slot in the these methods here
|
||||
Node *ps = Getattr(n, "sym:previousSibling");
|
||||
Node *ns = Getattr(n, "sym:nextSibling");
|
||||
Node *fc = firstChild(n);
|
||||
// The 'using' node results in methods being added in - slot in these methods here
|
||||
Node *pp = fc;
|
||||
|
||||
Node *firstoverloaded = Getattr(n, "sym:overloaded");
|
||||
if (firstoverloaded == n) {
|
||||
// This 'using' node we are cutting out was the first node in the overloaded list.
|
||||
// Change the first node in the list to its first sibling
|
||||
Delattr(firstoverloaded, "sym:overloaded");
|
||||
Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
|
||||
firstoverloaded = fc;
|
||||
while (nnn) {
|
||||
Setattr(nnn, "sym:overloaded", firstoverloaded);
|
||||
nnn = Getattr(nnn, "sym:nextSibling");
|
||||
}
|
||||
}
|
||||
while (pp) {
|
||||
Node *ppn = Getattr(pp, "sym:nextSibling");
|
||||
Setattr(pp, "sym:overloaded", firstoverloaded);
|
||||
|
@ -1209,18 +1209,15 @@ class TypePass:private Dispatcher {
|
|||
Setattr(ns, "sym:previousSibling", pp);
|
||||
Setattr(pp, "sym:nextSibling", ns);
|
||||
}
|
||||
#ifdef DEBUG_OVERLOADED
|
||||
debugnode = firstoverloaded;
|
||||
#endif
|
||||
}
|
||||
Delattr(n, "sym:previousSibling");
|
||||
Delattr(n, "sym:nextSibling");
|
||||
Delattr(n, "sym:overloaded");
|
||||
Delattr(n, "sym:overname");
|
||||
clean_overloaded(firstoverloaded);
|
||||
#ifdef DEBUG_OVERLOADED
|
||||
show_overloaded(debugnode);
|
||||
show_overloaded(firstoverloaded);
|
||||
#endif
|
||||
clean_overloaded(n); // Needed?
|
||||
}
|
||||
Delete(n_decl_list);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue