diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2022-03-06 11:37:27 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2022-03-10 22:18:23 +0000 |
commit | bd5ffe86e400855e8538da10d711a422f6c865ee (patch) | |
tree | 288f4a324a54df8f27ee066a99880217b3a035c3 | |
parent | 2a9431ebfb81d2ebcb1ce489fdf43d0f751df72a (diff) | |
download | swig-bd5ffe86e400855e8538da10d711a422f6c865ee.tar.gz |
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
-rw-r--r-- | CHANGES.current | 6 | ||||
-rw-r--r-- | Examples/test-suite/common.mk | 1 | ||||
-rw-r--r-- | Examples/test-suite/using_member_scopes.i | 31 | ||||
-rw-r--r-- | Source/Modules/typepass.cxx | 58 |
4 files changed, 74 insertions, 22 deletions
diff --git a/CHANGES.current b/CHANGES.current index ce8efe1bf..aa3939567 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -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 diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 22816c552..685882f80 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -554,6 +554,7 @@ CPP_TEST_CASES += \ using_extend \ using_inherit \ using_member \ + using_member_scopes \ using_namespace \ using_namespace_loop \ using_pointers \ diff --git a/Examples/test-suite/using_member_scopes.i b/Examples/test-suite/using_member_scopes.i new file mode 100644 index 000000000..bfd09902c --- /dev/null +++ b/Examples/test-suite/using_member_scopes.i @@ -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 + }; +*/ +} +%} diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index d3f8dc196..658f2e79c 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -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))) { |