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.
This commit is contained in:
Frank Schlimbach 2022-09-21 22:00:37 +01:00 committed by William S Fulton
commit fa00622614
4 changed files with 109 additions and 5 deletions

View file

@ -7,6 +7,13 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress) 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 2022-09-19: wsfulton
#2316 Remove swig.spec file and srcrpm makefile target. These are very out of date #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 and don't seem to be used by RPM based Linux distributions which have their

View file

@ -223,6 +223,7 @@ CPP_TEST_CASES += \
director_void \ director_void \
director_wombat \ director_wombat \
disown \ disown \
duplicate_class_name_in_ns \
dynamic_cast \ dynamic_cast \
empty \ empty \
enum_ignore \ enum_ignore \

View file

@ -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();}
%}

View file

@ -335,6 +335,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
if (tp) { if (tp) {
Symtab *tsdecl = Getattr(n, "sym:symtab"); Symtab *tsdecl = Getattr(n, "sym:symtab");
String *tsname = Getattr(n, "sym:name");
while (p && tp) { while (p && tp) {
String *name, *value, *valuestr, *tmp, *tmpr; String *name, *value, *valuestr, *tmp, *tmpr;
int sz, i; int sz, i;
@ -376,11 +377,18 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
sz = Len(typelist); sz = Len(typelist);
for (i = 0; i < sz; i++) { for (i = 0; i < sz; i++) {
String *s = Getitem(typelist, 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); */ The approach of 'trivially' replacing template arguments is kind of fragile.
SwigType_typename_replace(s, name, dvalue); In particular if types with similar name in different namespaces appear.
SwigType_typename_replace(s, tbase, iname); We will not replace template args if a type/class exists with the same
/* Printf(stdout,"'%s'\n", s); */ 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); tmp = NewStringf("#%s", name);