summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Schlimbach <frank.schlimbach@intel.com>2022-09-21 22:00:37 +0100
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2022-09-21 22:38:22 +0100
commitfa00622614d35716b429b12aa9dc1bde8e4b586d (patch)
tree15ecf101f6c51b211d45fb0a6cb25ee91c19a90b
parentee9e43697149de9c46676370f8a391f9a609fd76 (diff)
downloadswig-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.current7
-rw-r--r--Examples/test-suite/common.mk1
-rw-r--r--Examples/test-suite/duplicate_class_name_in_ns.i88
-rw-r--r--Source/CParse/templ.c18
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);