[D] Fixed a bug in the loop breaking code for directors leading to a superclass implementation erroneously being called.
The situation in which this would previously happen is illustrated in the new "director_alternating" test case. Currently broken for C# and Java. Thanks to Jimmy Cao for reporting this. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12380 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
25c8689226
commit
892caec201
6 changed files with 69 additions and 4 deletions
|
|
@ -154,6 +154,7 @@ CPP_TEST_CASES += \
|
||||||
derived_nested \
|
derived_nested \
|
||||||
destructor_reprotected \
|
destructor_reprotected \
|
||||||
director_abstract \
|
director_abstract \
|
||||||
|
director_alternating \
|
||||||
director_basic \
|
director_basic \
|
||||||
director_classes \
|
director_classes \
|
||||||
director_classic \
|
director_classic \
|
||||||
|
|
|
||||||
7
Examples/test-suite/d/director_alternating_runme.2.d
Normal file
7
Examples/test-suite/d/director_alternating_runme.2.d
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
module director_alternating_runme;
|
||||||
|
|
||||||
|
import director_alternating.director_alternating;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
assert(getBar().id() == idFromGetBar());
|
||||||
|
}
|
||||||
36
Examples/test-suite/director_alternating.i
Normal file
36
Examples/test-suite/director_alternating.i
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Checks if calls to a method being defined in the base class, not
|
||||||
|
// overridden in the subclass, but again overridden in a class derived from
|
||||||
|
// the first subclass are dispatched correctly.
|
||||||
|
%module(directors="1") director_alternating;
|
||||||
|
|
||||||
|
%feature("director") Foo;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Foo {
|
||||||
|
virtual ~Foo() {}
|
||||||
|
virtual int id() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Bar : Foo {};
|
||||||
|
|
||||||
|
struct Baz : Bar {
|
||||||
|
virtual int id() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note that even though the return value is of type Bar*, it really points to
|
||||||
|
// an instance of Baz (in which id() has been overridden).
|
||||||
|
Bar *getBar() {
|
||||||
|
static Baz baz;
|
||||||
|
return &baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// idFromGetBar() obviously is equivalent to getBar()->id() in C++ – this
|
||||||
|
// should be true from the target language as well.
|
||||||
|
int idFromGetBar() {
|
||||||
|
return getBar()->id();
|
||||||
|
}
|
||||||
|
%}
|
||||||
7
Examples/test-suite/director_alternating_runme.1.d
Normal file
7
Examples/test-suite/director_alternating_runme.1.d
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
module director_alternating_runme;
|
||||||
|
|
||||||
|
import director_alternating.director_alternating;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
assert(getBar().id() == idFromGetBar());
|
||||||
|
}
|
||||||
5
Examples/test-suite/python/director_alternating_runme.py
Normal file
5
Examples/test-suite/python/director_alternating_runme.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
from director_alternating import *
|
||||||
|
|
||||||
|
id = getBar().id()
|
||||||
|
if id != idFromGetBar():
|
||||||
|
raise RuntimeError, "Got wrong id: " + str(id)
|
||||||
|
|
@ -2630,6 +2630,8 @@ private:
|
||||||
if (!static_flag) {
|
if (!static_flag) {
|
||||||
Printf(imcall, "cast(void*)swigCPtr");
|
Printf(imcall, "cast(void*)swigCPtr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String *proxy_param_types = NewString("");
|
||||||
|
|
||||||
// Write the parameter list for the proxy function declaration and the
|
// Write the parameter list for the proxy function declaration and the
|
||||||
// wrapper function call.
|
// wrapper function call.
|
||||||
|
|
@ -2704,10 +2706,13 @@ private:
|
||||||
"No dtype typemap defined for %s\n", SwigType_str(pt, 0));
|
"No dtype typemap defined for %s\n", SwigType_str(pt, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gencomma >= 2)
|
if (gencomma >= 2) {
|
||||||
Printf(function_code, ", ");
|
Printf(function_code, ", ");
|
||||||
|
Printf(proxy_param_types, ", ");
|
||||||
|
}
|
||||||
gencomma = 2;
|
gencomma = 2;
|
||||||
Printf(function_code, "%s %s", proxy_type, param_name);
|
Printf(function_code, "%s %s", proxy_type, param_name);
|
||||||
|
Append(proxy_param_types, proxy_type);
|
||||||
|
|
||||||
Delete(proxy_type);
|
Delete(proxy_type);
|
||||||
}
|
}
|
||||||
|
|
@ -2772,9 +2777,11 @@ private:
|
||||||
|
|
||||||
String *excode = NewString("");
|
String *excode = NewString("");
|
||||||
if (!Cmp(return_type, "void"))
|
if (!Cmp(return_type, "void"))
|
||||||
Printf(excode, "if (this.classinfo == %s.classinfo) %s; else %s", proxy_class_name, imcall, ex_imcall);
|
Printf(excode, "if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) %s; else %s",
|
||||||
|
return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
|
||||||
else
|
else
|
||||||
Printf(excode, "((this.classinfo == %s.classinfo) ? %s : %s)", proxy_class_name, imcall, ex_imcall);
|
Printf(excode, "((swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) ? %s : %s)",
|
||||||
|
return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
|
||||||
|
|
||||||
Clear(imcall);
|
Clear(imcall);
|
||||||
Printv(imcall, excode, NIL);
|
Printv(imcall, excode, NIL);
|
||||||
|
|
@ -2788,6 +2795,8 @@ private:
|
||||||
Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
|
Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
|
||||||
"No dout typemap defined for %s\n", SwigType_str(t, 0));
|
"No dout typemap defined for %s\n", SwigType_str(t, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(proxy_param_types);
|
||||||
|
|
||||||
// The whole function body is now in stored tm (if there was a matching type
|
// The whole function body is now in stored tm (if there was a matching type
|
||||||
// map, of course), so simply append it to the code buffer. The braces are
|
// map, of course), so simply append it to the code buffer. The braces are
|
||||||
|
|
@ -3418,7 +3427,7 @@ private:
|
||||||
// Only emit it if the proxy class has at least one method.
|
// Only emit it if the proxy class has at least one method.
|
||||||
if (first_class_dmethod < curr_class_dmethod) {
|
if (first_class_dmethod < curr_class_dmethod) {
|
||||||
Printf(proxy_class_body_code, "\n");
|
Printf(proxy_class_body_code, "\n");
|
||||||
Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() {\n");
|
Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() %s{\n", (d_version > 1) ? "const " : "");
|
||||||
Printf(proxy_class_body_code, " DelegateType dg = &fn;\n");
|
Printf(proxy_class_body_code, " DelegateType dg = &fn;\n");
|
||||||
Printf(proxy_class_body_code, " return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n");
|
Printf(proxy_class_body_code, " return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n");
|
||||||
Printf(proxy_class_body_code, "}\n");
|
Printf(proxy_class_body_code, "}\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue