C++11 using declarations for template classes with non-template base classes

This commit is contained in:
William S Fulton 2023-07-07 12:00:48 +01:00
parent eecee6a556
commit 5b9179ea7e
6 changed files with 91 additions and 4 deletions

View File

@ -242,6 +242,7 @@ struct HiddenDerived1 : HiddenBase1 {
};
%}
#if 0 // not yet working
// Typedefs and using declarations
%inline %{
struct TypedefBase1 {
@ -257,3 +258,35 @@ void tester() {
td.meth();
}
%}
#endif
%inline %{
// Templates and public base constructors (derive from non-template)
template<typename T>
struct TemplatePublicDerived1 : PublicBase1 {
using PublicBase1::PublicBase1;
using PublicBase1::meth;
};
template<typename T>
struct TemplatePublicDerived2 : PublicBase2 {
using PublicBase2::PublicBase2;
using PublicBase2::meth;
};
template<typename T>
struct TemplatePublicDerived3 : PublicBase3 {
using PublicBase3::PublicBase3;
using PublicBase3::meth;
};
template<typename T>
struct TemplatePublicDerived4 : PublicBase4 {
using PublicBase4::PublicBase4;
using PublicBase4::meth;
};
%}
%template(TemplatePublicDerived1Int) TemplatePublicDerived1<int>;
%template(TemplatePublicDerived2Int) TemplatePublicDerived2<int>;
%template(TemplatePublicDerived3Int) TemplatePublicDerived3<int>;
%template(TemplatePublicDerived4Int) TemplatePublicDerived4<int>;

View File

@ -89,6 +89,15 @@ public class cpp11_using_constructor_runme {
new ProotDerived2f(0).meth();
// Missing base
new HiddenDerived1();
// new HiddenDerived1();
// Templates and public base constructors (derive from non-template)
new TemplatePublicDerived1Int(0, "hi").meth();
new TemplatePublicDerived2Int().meth();
new TemplatePublicDerived2Int(0, "hi").meth();
new TemplatePublicDerived3Int().meth();
new TemplatePublicDerived3Int(0, "hi").meth();
new TemplatePublicDerived4Int().meth();
}
}

View File

@ -77,4 +77,12 @@ ProotDerived2f().meth()
ProotDerived2f(0).meth()
# Missing base
HiddenDerived1()
# HiddenDerived1()
# Templates and public base constructors (derive from non-template)
TemplatePublicDerived1Int(0, "hi").meth()
TemplatePublicDerived2Int().meth()
TemplatePublicDerived2Int(0, "hi").meth()
TemplatePublicDerived3Int().meth()
TemplatePublicDerived3Int(0, "hi").meth()
TemplatePublicDerived4Int().meth()

View File

@ -466,7 +466,7 @@ static void add_symbols(Node *n) {
if (Equal(ntype, "constructor")) {
// The using declaration name for inheriting constructors is the base class constructor name
// not the name provided by the using declaration. Correct it here.
String *nname = Getattr(currentOuterClass, "name");
String *nname = Getattr(stab, "name");
Setattr(n, "name", nname);
}
}

View File

@ -288,10 +288,47 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
Append(cpatchlist, Getattr(n, "code"));
}
} else if (Equal(nodeType, "using")) {
String *name = Getattr(n, "name");
String *uname = Getattr(n, "uname");
if (uname && strchr(Char(uname), '<')) {
Append(patchlist, uname);
}
if (!(Getattr(n, "templatetype"))) {
// Copied from handling "constructor" .. not sure if all this is needed
String *symname;
String *stripped_name = SwigType_templateprefix(name);
if (Strstr(tname, stripped_name)) {
Replaceid(name, stripped_name, tname);
}
Delete(stripped_name);
symname = Getattr(n, "sym:name");
if (symname) {
stripped_name = SwigType_templateprefix(symname);
if (Strstr(tname, stripped_name)) {
Replaceid(symname, stripped_name, tname);
}
Delete(stripped_name);
}
if (strchr(Char(name), '<')) {
Append(patchlist, Getattr(n, "name"));
} else {
Append(name, templateargs);
}
name = Getattr(n, "sym:name");
if (name) {
if (strchr(Char(name), '<')) {
Clear(name);
Append(name, rname);
} else {
String *tmp = Copy(name);
Replace(tmp, tname, rname, DOH_REPLACE_ANY);
Clear(name);
Append(name, tmp);
Delete(tmp);
}
}
}
if (Getattr(n, "namespace")) {
/* Namespace link. This is nasty. Is other namespace defined? */

View File

@ -1048,7 +1048,7 @@ class TypePass:private Dispatcher {
|| GetFlag(c, "feature:ignore"))) {
String *csymname = Getattr(c, "sym:name");
bool using_inherited_constructor_symname_okay = Equal(nodeType(c), "constructor") && Equal(symname, Getattr(parentNode(n), "name"));
bool using_inherited_constructor_symname_okay = Equal(nodeType(c), "constructor") && Equal(symname, Getattr(parentNode(n), "sym:name"));
if (!csymname || Equal(csymname, symname) || using_inherited_constructor_symname_okay) {
String *decl = Getattr(c, "decl");
int match = 0;