diff options
author | Frank Schlimbach <frank.schlimbach@intel.com> | 2022-09-21 22:00:37 +0100 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2022-09-21 22:38:22 +0100 |
commit | fa00622614d35716b429b12aa9dc1bde8e4b586d (patch) | |
tree | 15ecf101f6c51b211d45fb0a6cb25ee91c19a90b | |
parent | ee9e43697149de9c46676370f8a391f9a609fd76 (diff) | |
download | swig-fa00622614d35716b429b12aa9dc1bde8e4b586d.tar.gz |
Fixes for classes with the same name in different namespaces
Includes the majority of patch #1484.
Excludes changes in typepass.cxx for specializations which have no effect
on the duplicate_class_name_in_ns testcase, nor the rest of the test-suite.
-rw-r--r-- | CHANGES.current | 7 | ||||
-rw-r--r-- | Examples/test-suite/common.mk | 1 | ||||
-rw-r--r-- | Examples/test-suite/duplicate_class_name_in_ns.i | 88 | ||||
-rw-r--r-- | Source/CParse/templ.c | 18 |
4 files changed, 109 insertions, 5 deletions
diff --git a/CHANGES.current b/CHANGES.current index fd180c31c..6df9d6c5f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -8,6 +8,13 @@ Version 4.1.0 (in progress) =========================== 2022-09-19: wsfulton + #1484 Fixes for class inheritance with the same name in different namespaces + such as: + + namespace A { class Bar {}; } + namespace B { template<typename T, typename U> class Bar : public A::Bar {}; } + +2022-09-19: wsfulton #2316 Remove swig.spec file and srcrpm makefile target. These are very out of date and don't seem to be used by RPM based Linux distributions which have their own version of swig.spec. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 64057fbcb..da90dd9fd 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -223,6 +223,7 @@ CPP_TEST_CASES += \ director_void \ director_wombat \ disown \ + duplicate_class_name_in_ns \ dynamic_cast \ empty \ enum_ignore \ diff --git a/Examples/test-suite/duplicate_class_name_in_ns.i b/Examples/test-suite/duplicate_class_name_in_ns.i new file mode 100644 index 000000000..8071f08b7 --- /dev/null +++ b/Examples/test-suite/duplicate_class_name_in_ns.i @@ -0,0 +1,88 @@ +%module duplicate_class_name_in_ns + +%rename(XA) A::X; +%rename(XB) B::X; + +%inline %{ + +namespace A +{ + class X + { + public: + X(){}; + }; + + template<typename T> + class Foo + { + public: + Foo(){}; + }; + + class Bar + { + public: + Bar(){}; + }; + + template<typename T> + class Baz + { + public: + Baz(){}; + }; +} + +namespace B +{ + // non-template derived from non-template + class X : public A::X + { + public: + X(){}; + A::X do_x(){return A::X();} + }; + + // template derived from template with different template args + template<typename T, typename U> + class Foo : public A::Foo<U> + { + public: + Foo(){}; + A::Foo<U> do_foo(){return A::Foo<U>();} + }; + + // template derived from non-template + template<typename T, typename U> + class Bar : public A::Bar + { + public: + Bar(){}; + A::Bar do_bar(){return A::Bar();} + }; + + // template derived from template with same template args + template<typename T> + class Baz : public A::Baz<T> + { + public: + Baz(){}; + A::Baz<T> do_baz(){return A::Baz<T>();} + }; +} + +%} + +%template(AFoo) A::Foo<double>; +%template(ABaz) A::Baz<double>; +%template(BFoo) B::Foo<int, double>; +%template(BBar) B::Bar<int, double>; +%template(BBaz) B::Baz<double>; + +%inline %{ + A::X get_a_x() {B::X x; return x.do_x();} + A::Foo<double> get_a_foo() {B::Foo<int, double> x; return x.do_foo();} + A::Bar get_a_bar() {B::Bar<int, double> x; return x.do_bar();} + A::Baz<double> get_a_baz() {B::Baz<double> x; return x.do_baz();} +%} diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 44a606299..8dc6a7315 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -335,6 +335,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab if (tp) { Symtab *tsdecl = Getattr(n, "sym:symtab"); + String *tsname = Getattr(n, "sym:name"); while (p && tp) { String *name, *value, *valuestr, *tmp, *tmpr; int sz, i; @@ -376,11 +377,18 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist, i); - /* Replace(s,name,value, DOH_REPLACE_ID); */ - /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */ - SwigType_typename_replace(s, name, dvalue); - SwigType_typename_replace(s, tbase, iname); - /* Printf(stdout,"'%s'\n", s); */ + /* + The approach of 'trivially' replacing template arguments is kind of fragile. + In particular if types with similar name in different namespaces appear. + We will not replace template args if a type/class exists with the same + name which is not a template. + */ + Node * tynode = Swig_symbol_clookup(s, 0); + String *tyname = tynode ? Getattr(tynode, "sym:name") : 0; + if (!tyname || !tsname || !Equal(tyname, tsname) || Getattr(tynode, "templatetype")) { + SwigType_typename_replace(s, name, dvalue); + SwigType_typename_replace(s, tbase, iname); + } } tmp = NewStringf("#%s", name); |