Fix templated constructors regression

Templated constructors were incorrectly ignored because SWIG thought they were
methods without a return type.
Regression introduced in swig-3.0.0
Closes #245.
This commit is contained in:
William S Fulton 2014-12-09 23:31:07 +00:00
commit ae555c2339
5 changed files with 81 additions and 1 deletions

View file

@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.3 (in progress)
===========================
2014-12-09: wsfulton
Fix #245 - regression (since swig-3.0.0) in templated constructors.
Templated constructors could not be instantiated - they were incorrectly ignored with a warning 504:
"Function: xyz must have a return type. Ignored."
2014-12-07: wsfulton
Add support for C++11 strongly typed enumerations.

View file

@ -382,6 +382,7 @@ CPP_TEST_CASES += \
template_classes \
template_const_ref \
template_construct \
template_templated_constructors \
template_default \
template_default2 \
template_default_arg \

View file

@ -0,0 +1,26 @@
import template_templated_constructors.*;
public class template_templated_constructors_runme {
static {
try {
System.loadLibrary("template_templated_constructors");
} 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[]) {
TConstructor1 t1 = new TConstructor1(123);
TConstructor2 t2a = new TConstructor2();
TConstructor2 t2b = new TConstructor2(123);
TClass1Int tc1 = new TClass1Int(123.4);
TClass2Int tc2a = new TClass2Int();
TClass2Int tc2b = new TClass2Int(123.4);
}
}

View file

@ -0,0 +1,47 @@
%module template_templated_constructors
%inline %{
namespace ConstructSpace {
class TConstructor1 {
public:
template<typename T> TConstructor1(T val) {}
~TConstructor1() {}
};
class TConstructor2 {
public:
TConstructor2() {}
template<typename T> TConstructor2(T val) {}
~TConstructor2() {}
};
template<typename T> class TClass1 {
public:
template<typename Y> TClass1(Y t) {}
};
template<typename T> class TClass2 {
public:
TClass2() {}
template<typename Y> TClass2(Y t) {}
};
}
%}
%extend ConstructSpace::TConstructor1 {
%template(TConstructor1) TConstructor1<int>;
}
%template(TConstructor2) ConstructSpace::TConstructor2::TConstructor2<int>;
%template(TClass1Int) ConstructSpace::TClass1<int>;
%extend ConstructSpace::TClass1<int> {
%template(TClass1Int) TClass1<double>;
}
%template(TClass2Int) ConstructSpace::TClass2<int>;
%extend ConstructSpace::TClass2<int> {
%template(TClass2Int) TClass2<double>;
}

View file

@ -2694,7 +2694,8 @@ int Language::constructorDeclaration(Node *n) {
String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
Delete(scope);
if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name)) {
if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name) && !SwigType_istemplate(actual_name)) {
// Checking templates is skipped but they ought to be checked... they are just somewhat more tricky to check correctly
bool illegal_name = true;
if (Extend) {
// Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous