Using declarations in derived class parameters scoping fix
Fix using declaration in derived class incorrectly introducing a method from a base class when the using declaration is declared before the method declaration. Problem occurred when within a namespace and the parameter types in the method signatures were not fully qualified. Issue #1441
This commit is contained in:
parent
2a9431ebfb
commit
bd5ffe86e4
4 changed files with 74 additions and 22 deletions
|
|
@ -38,6 +38,12 @@ Version 4.1.0 (in progress)
|
|||
Also SWIG/Javascript tried to exit with status -1 in a few places
|
||||
(which typically results in exit status 255).
|
||||
|
||||
2022-03-05: wsfulton
|
||||
#1441 Fix using declaration in derived class incorrectly introducing a method
|
||||
from a base class when the using declaration is declared before the method
|
||||
declaration. Problem occurred when within a namespace and the parameter types
|
||||
in the method signatures were not fully qualified.
|
||||
|
||||
2022-03-03: olly
|
||||
#1901 #2223 SWIG should now always exit cleanly if memory
|
||||
allocation fails, including removing any output files created
|
||||
|
|
|
|||
|
|
@ -554,6 +554,7 @@ CPP_TEST_CASES += \
|
|||
using_extend \
|
||||
using_inherit \
|
||||
using_member \
|
||||
using_member_scopes \
|
||||
using_namespace \
|
||||
using_namespace_loop \
|
||||
using_pointers \
|
||||
|
|
|
|||
31
Examples/test-suite/using_member_scopes.i
Normal file
31
Examples/test-suite/using_member_scopes.i
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
%module using_member_scopes
|
||||
|
||||
// Fully qualifying parameter types in a method declared after the using declaration caused
|
||||
// a method being incorrectly added by the using declaration even though the declaration already existed
|
||||
|
||||
%inline %{
|
||||
namespace OgreBites
|
||||
{
|
||||
struct NativeWindowType {};
|
||||
class ApplicationContextBase {
|
||||
public:
|
||||
virtual ~ApplicationContextBase() {}
|
||||
virtual void setWindowGrab(NativeWindowType* win, bool grab = true) {}
|
||||
void setWindowGrab(bool grab = true) {}
|
||||
};
|
||||
class ApplicationContextSDL : public ApplicationContextBase {
|
||||
public:
|
||||
using ApplicationContextBase::setWindowGrab;
|
||||
void setWindowGrab(NativeWindowType* win, bool grab) {} // This should not be added again as it exists in base class
|
||||
};
|
||||
/*
|
||||
typedef not working yet
|
||||
class ApplicationContextSDL2 : public ApplicationContextBase {
|
||||
public:
|
||||
using ApplicationContextBase::setWindowGrab;
|
||||
typedef NativeWindowType* pNWT;
|
||||
void setWindowGrab(pNWT win, bool grab) {} // This should not be added again as it exists in base class
|
||||
};
|
||||
*/
|
||||
}
|
||||
%}
|
||||
|
|
@ -1039,6 +1039,21 @@ class TypePass:private Dispatcher {
|
|||
Node *unodes = 0, *last_unodes = 0;
|
||||
int ccount = 0;
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
|
||||
// The overloaded functions in scope may not yet have had their parameters normalized yet (in cDeclaration).
|
||||
// Happens if the functions were declared after the using declaration. So use a normalized copy.
|
||||
List *n_decl_list = NewList();
|
||||
Node *over = Getattr(n, "sym:overloaded");
|
||||
while (over) {
|
||||
String *odecl = Copy(Getattr(over, "decl"));
|
||||
if (odecl) {
|
||||
normalize_type(odecl);
|
||||
Append(n_decl_list, odecl);
|
||||
Delete(odecl);
|
||||
}
|
||||
over = Getattr(over, "sym:nextSibling");
|
||||
}
|
||||
|
||||
while (c) {
|
||||
if (Strcmp(nodeType(c), "cdecl") == 0) {
|
||||
if (!(Swig_storage_isstatic(c)
|
||||
|
|
@ -1049,30 +1064,28 @@ class TypePass:private Dispatcher {
|
|||
|
||||
String *csymname = Getattr(c, "sym:name");
|
||||
if (!csymname || (Strcmp(csymname, symname) == 0)) {
|
||||
{
|
||||
String *decl = Getattr(c, "decl");
|
||||
Node *over = Getattr(n, "sym:overloaded");
|
||||
int match = 0;
|
||||
while (over) {
|
||||
String *odecl = Getattr(over, "decl");
|
||||
if (Cmp(decl, odecl) == 0) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
over = Getattr(over, "sym:nextSibling");
|
||||
}
|
||||
if (match) {
|
||||
/* Don't generate a method if the method is overridden in this class,
|
||||
* for example don't generate another m(bool) should there be a Base::m(bool) :
|
||||
* struct Derived : Base {
|
||||
* void m(bool);
|
||||
* using Base::m;
|
||||
* };
|
||||
*/
|
||||
c = Getattr(c, "csym:nextSibling");
|
||||
continue;
|
||||
String *decl = Getattr(c, "decl");
|
||||
int match = 0;
|
||||
|
||||
for (Iterator it = First(n_decl_list); it.item; it = Next(it)) {
|
||||
String *odecl = it.item;
|
||||
if (Cmp(decl, odecl) == 0) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
/* Don't generate a method if the method is overridden in this class,
|
||||
* for example don't generate another m(bool) should there be a Base::m(bool) :
|
||||
* struct Derived : Base {
|
||||
* void m(bool);
|
||||
* using Base::m;
|
||||
* };
|
||||
*/
|
||||
c = Getattr(c, "csym:nextSibling");
|
||||
continue;
|
||||
}
|
||||
|
||||
Node *nn = copyNode(c);
|
||||
Setfile(nn, Getfile(n));
|
||||
Setline(nn, Getline(n));
|
||||
|
|
@ -1206,6 +1219,7 @@ class TypePass:private Dispatcher {
|
|||
#endif
|
||||
clean_overloaded(n); // Needed?
|
||||
}
|
||||
Delete(n_decl_list);
|
||||
}
|
||||
}
|
||||
} else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue