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:
parent
ee9e436971
commit
fa00622614
4 changed files with 109 additions and 5 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 \
|
||||||
|
|
|
||||||
88
Examples/test-suite/duplicate_class_name_in_ns.i
Normal file
88
Examples/test-suite/duplicate_class_name_in_ns.i
Normal 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();}
|
||||||
|
%}
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue