mirror of https://github.com/swig/swig
Constructors and destructors declared with template parameters
Recent commits for internal constructor and destructor names resulted in destructors declared with template parameters being ignored with warnings like: Illegal destructor name TemplPublicBase6< int >::~TemplPublicBase6(). Ignored. Although declaring constructors and destructors with template parameters are rejected by modern compilers and C++20, SWIG continues to support it. Make sure the name stored in the parse tree is the C++20 compliant name name, that is, without the template parameters. Fixes using declarations for templated constructors declared with template parameters, was warning with: Nothing known about 'TemplPublicBase6< int >::TemplPublicBase6'.
This commit is contained in:
parent
0830c96e1b
commit
2ff9da0ce6
|
@ -1,5 +1,7 @@
|
|||
%module cpp11_using_constructor
|
||||
|
||||
// Note: this testcase is also used by cpp11_director_using_constructor.i
|
||||
|
||||
%inline %{
|
||||
// Public base constructors
|
||||
struct PublicBase1 {
|
||||
|
@ -406,6 +408,22 @@ struct TemplPublicBase5 {
|
|||
// implicit constructor
|
||||
virtual void meth() {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct TemplPublicBase6 {
|
||||
#ifdef SWIG
|
||||
// Destructor and constructor declared with template parameters (not allowed in C++20 and later though)
|
||||
virtual ~TemplPublicBase6<T>() {}
|
||||
TemplPublicBase6<T>(T i, const char* s) {}
|
||||
TemplPublicBase6<T>() = default;
|
||||
#else
|
||||
virtual ~TemplPublicBase6() {}
|
||||
TemplPublicBase6(T i, const char* s) {}
|
||||
TemplPublicBase6() = default;
|
||||
#endif
|
||||
virtual void meth() {}
|
||||
};
|
||||
|
||||
%}
|
||||
|
||||
%template(TemplPublicBase1Int) TemplPublicBase1<int>;
|
||||
|
@ -413,6 +431,7 @@ struct TemplPublicBase5 {
|
|||
%template(TemplPublicBase3Int) TemplPublicBase3<int>;
|
||||
%template(TemplPublicBase4Int) TemplPublicBase4<int>;
|
||||
%template(TemplPublicBase5Int) TemplPublicBase5<int>;
|
||||
%template(TemplPublicBase6Int) TemplPublicBase6<int>;
|
||||
|
||||
%inline %{
|
||||
template<typename T>
|
||||
|
@ -440,6 +459,11 @@ struct TemplPublicDerived5 : TemplPublicBase5<T> {
|
|||
using TemplPublicBase5<T>::TemplPublicBase5;
|
||||
using TemplPublicBase5<T>::meth;
|
||||
};
|
||||
template<typename T>
|
||||
struct TemplPublicDerived6 : TemplPublicBase6<T> {
|
||||
using TemplPublicBase6<T>::TemplPublicBase6;
|
||||
using TemplPublicBase6<T>::meth;
|
||||
};
|
||||
%}
|
||||
|
||||
%template(TemplPublicDerived1Int) TemplPublicDerived1<int>;
|
||||
|
@ -447,3 +471,4 @@ struct TemplPublicDerived5 : TemplPublicBase5<T> {
|
|||
%template(TemplPublicDerived3Int) TemplPublicDerived3<int>;
|
||||
%template(TemplPublicDerived4Int) TemplPublicDerived4<int>;
|
||||
%template(TemplPublicDerived5Int) TemplPublicDerived5<int>;
|
||||
%template(TemplPublicDerived6Int) TemplPublicDerived6<int>;
|
||||
|
|
|
@ -127,6 +127,8 @@ public class cpp11_director_using_constructor_runme {
|
|||
new TemplPublicDerived3Int(0, "hi").meth();
|
||||
new TemplPublicDerived4Int().meth();
|
||||
new TemplPublicDerived5Int().meth();
|
||||
new TemplPublicDerived6Int(0, "hi").meth();
|
||||
new TemplPublicDerived6Int().meth();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -125,5 +125,7 @@ public class cpp11_using_constructor_runme {
|
|||
new TemplPublicDerived3Int(0, "hi").meth();
|
||||
new TemplPublicDerived4Int().meth();
|
||||
new TemplPublicDerived5Int().meth();
|
||||
new TemplPublicDerived6Int(0, "hi").meth();
|
||||
new TemplPublicDerived6Int().meth();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
import template_construct.*;
|
||||
|
||||
public class template_construct_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("template_construct");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
Foo_int fi = new Foo_int(0);
|
||||
fi.delete();
|
||||
Foo_short fs = new Foo_short();
|
||||
fs.delete();
|
||||
fs = new Foo_short();
|
||||
fs.delete();
|
||||
}
|
||||
}
|
||||
|
|
@ -113,3 +113,5 @@ TemplPublicDerived3Int().meth()
|
|||
TemplPublicDerived3Int(0, "hi").meth()
|
||||
TemplPublicDerived4Int().meth()
|
||||
TemplPublicDerived5Int().meth()
|
||||
TemplPublicDerived6Int(0, "hi").meth()
|
||||
TemplPublicDerived6Int().meth()
|
||||
|
|
|
@ -1,21 +1,43 @@
|
|||
%module template_construct
|
||||
|
||||
// Tests templates to make sure an extra <> in a constructor is ok.
|
||||
// Tests templates to make sure an extra <> in a constructor and destructor is ok.
|
||||
|
||||
%inline %{
|
||||
template<class T>
|
||||
template<class T>
|
||||
class Foo {
|
||||
T y;
|
||||
public:
|
||||
#ifdef SWIG
|
||||
Foo<T>(T x) : y(x) { }
|
||||
~Foo<T>() {}
|
||||
#else
|
||||
// Modern compilers reject this, so feed the compiler the corrected
|
||||
// version.
|
||||
// Modern compilers (C++20) reject this, so feed the compiler the corrected version
|
||||
Foo(T x) : y(x) { }
|
||||
~Foo() {}
|
||||
#endif
|
||||
};
|
||||
|
||||
%}
|
||||
|
||||
%template(Foo_int) Foo<int>;
|
||||
|
||||
%inline %{
|
||||
template<>
|
||||
class Foo<short> {
|
||||
short y;
|
||||
public:
|
||||
#ifdef SWIG
|
||||
Foo<short>(short x) : y(x) { }
|
||||
Foo<short>() : y(0) { }
|
||||
virtual ~Foo<short>() {}
|
||||
#else
|
||||
// Modern compilers (C++20) reject this, so feed the compiler the corrected version
|
||||
// version.
|
||||
Foo(short x) : y(x) { }
|
||||
Foo() : y(0) { }
|
||||
virtual ~Foo() {}
|
||||
#endif
|
||||
};
|
||||
%}
|
||||
|
||||
%template(Foo_short) Foo<short>;
|
||||
|
|
|
@ -4769,10 +4769,11 @@ cpp_member : cpp_member_no_dox
|
|||
|
||||
cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
|
||||
if (inclass || extendmode) {
|
||||
String *name = SwigType_templateprefix($2); /* A constructor can optionally be declared with template parameters before C++20, strip these off */
|
||||
SwigType *decl = NewStringEmpty();
|
||||
$$ = new_node("constructor");
|
||||
Setattr($$,"storage",$1);
|
||||
Setattr($$,"name",$2);
|
||||
Setattr($$, "name", name);
|
||||
Setattr($$,"parms",$4);
|
||||
SwigType_add_function(decl,$4);
|
||||
Setattr($$,"decl",decl);
|
||||
|
@ -4798,9 +4799,9 @@ cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
|
|||
/* A destructor (hopefully) */
|
||||
|
||||
cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
|
||||
String *name = NewStringf("%s",$2);
|
||||
if (*(Char(name)) != '~') Insert(name,0,"~");
|
||||
$$ = new_node("destructor");
|
||||
String *name = SwigType_templateprefix($2); /* A destructor can optionally be declared with template parameters before C++20, strip these off */
|
||||
Insert(name, 0, "~");
|
||||
$$ = new_node("destructor");
|
||||
Setattr($$,"name",name);
|
||||
Delete(name);
|
||||
if (Len(scanner_ccode)) {
|
||||
|
@ -4828,11 +4829,10 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
|
|||
/* A virtual destructor */
|
||||
|
||||
| VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
|
||||
String *name;
|
||||
String *name = SwigType_templateprefix($3); /* A destructor can optionally be declared with template parameters before C++20, strip these off */
|
||||
Insert(name, 0, "~");
|
||||
$$ = new_node("destructor");
|
||||
Setattr($$,"storage","virtual");
|
||||
name = NewStringf("%s",$3);
|
||||
if (*(Char(name)) != '~') Insert(name,0,"~");
|
||||
Setattr($$,"name",name);
|
||||
Delete(name);
|
||||
Setattr($$,"throws",$7.throws);
|
||||
|
|
Loading…
Reference in New Issue