- explicitcall feature removed.
- Instead of using the swig_up flag in each director method (Python, Ruby, Ocaml) to indicate whether the explicit C++ call to the appropriate base class method or a normal polymorphic C++ call should be made, the new approach makes one of these calls directly from the wrapper method. - Java/C# recursive director method calls fixed (no need for explicitcall feature to solve this now) git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9275 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
a19cc4444e
commit
f0d1d772fa
12 changed files with 355 additions and 303 deletions
|
|
@ -83,7 +83,6 @@
|
|||
<li><a href="#java_directors_classes">Director classes</a>
|
||||
<li><a href="#java_directors_overhead">Overhead and code bloat</a>
|
||||
<li><a href="#java_directors_example">Simple directors example</a>
|
||||
<li><a href="#java_directors_explicitcall">Director base method calls</a>
|
||||
</ul>
|
||||
<li><a href="#common_customization">Common customization features</a>
|
||||
<ul>
|
||||
|
|
@ -3204,62 +3203,6 @@ directorDerived::upcall_method() invoked.
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="java_directors_explicitcall"></a>20.5.5 Director base method calls</H3>
|
||||
|
||||
|
||||
<p>
|
||||
There is a limitation with Java directors when calling a base class method from an overridden method.
|
||||
A <tt>java.lang.StackOverflowError</tt> exception will be thrown as the code makes recursive calls from the C++ layer
|
||||
to the Java layer and back again in the same method. The <a href="SWIGPlus.html#SWIGPlus_explicitcall">explicitcall feature flag</a>
|
||||
is one way to work around this problem. Consider the following C++ code:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("director");
|
||||
%feature("explicitcall");
|
||||
%include <std_string.i>
|
||||
|
||||
%inline %{
|
||||
struct Thing {
|
||||
virtual std::string getit() { return "Thing"; }
|
||||
virtual ~Thing() {}
|
||||
};
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
and the following Java class:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class JavaThing extends Thing {
|
||||
public String getit() {
|
||||
return "Java" + super.getit();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The overridden <tt>JavaThing.getit()</tt> method will throw the <tt>java.lang.StackOverflowError</tt> exception when called.
|
||||
Fixing this would impose a performance penalty on all director methods and would not be able to automatically deal with pure
|
||||
virtual methods for which a method body is not always defined. Instead, users are advised to use the explicitcall
|
||||
feature flag which generates an additional method <tt>getitThing()</tt>. The modified version will then avoid the recursive calls:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class JavaThing extends Thing {
|
||||
public String getit() {
|
||||
return "Java" + super.getitThing();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H2><a name="common_customization"></a>20.6 Common customization features</H2>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1668,86 +1668,6 @@ functions for virtual members that are already defined in a base
|
|||
class.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIGPlus_explicitcall"></a>6.13.1 Explicit base class method calls</H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG uses standard C++ polymorphic behaviour to ensure the correct virtual method is called
|
||||
when generating wrappers for virtual methods.
|
||||
However, in C++ it is possible, albeit rare, to call a particular base class method in the inheritance
|
||||
hierarchy. This C++ functionality is available to target languages with the
|
||||
<tt>explicitcall</tt> <a href="Customization.html#Customization_feature_flags">feature flag</a> directive.
|
||||
This feature only works on virtual methods and when it is specified it generates an
|
||||
additional wrapper method. By default, the name of this method is the original method name mangled with
|
||||
the name of the class as a suffix. However, the name of the method can be controlled by specifying a different
|
||||
suffix in the <tt>suffix</tt>
|
||||
<a href="Customization.html#Customization_feature_attributes">feature attribute</a>.
|
||||
For example, consider the following code:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%explicitcall; // enable explicitcall feature for all virtual methods
|
||||
%feature("explicitcall", suffix="Bambino") Child::describe;
|
||||
|
||||
struct Person {
|
||||
Person() {}
|
||||
virtual const char * describe() { return "Person"; }
|
||||
virtual ~Person() {}
|
||||
};
|
||||
|
||||
struct Child : Person {
|
||||
virtual const char * describe() { return "Child"; }
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
From Python, it is then possible to call explicit methods in the inheritance hierarchy.
|
||||
Note the suffix names:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
$ python
|
||||
>>> from example import *
|
||||
>>> child = Child()
|
||||
>>> print child.describe() # normal polymorphic call
|
||||
Child
|
||||
>>> print child.describePerson() # explicit Person::describe call
|
||||
Person
|
||||
>>> print child.describeBambino() # explicit Child::describe call
|
||||
Child
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The pseudo C++ code generated for the <tt>Person::describe</tt> methods is as follows:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// Normal virtual method wrapper
|
||||
const char * Person_talk(Person *obj) {
|
||||
const char * ret = obj->describe();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Additional wrapper due to %explicitcall
|
||||
const char * Person_talkPerson(Person *obj) {
|
||||
const char * ret = obj->Person::describe();
|
||||
return ret;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Please note that if this feature is enabled globally, it will apply to all virtual methods.
|
||||
This includes pure virtual methods which may or may not have a body defined.
|
||||
If, as is often the case, your pure virtual methods do not have a body defined you might get unresolved linker errors on some platforms.
|
||||
<tt>%noexplicitcall</tt> can then be used to turn this feature off for the problem methods.
|
||||
</p>
|
||||
|
||||
<H2><a name="SWIGPlus_nn21"></a>6.14 A brief discussion of multiple inheritance, pointers, and type checking</H2>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1859,6 +1859,9 @@ class CSHARP : public Language {
|
|||
// Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
|
||||
if (Getattr(n, "overload:ignore")) return;
|
||||
|
||||
// Don't generate proxy method for additional explicitcall method used in directors
|
||||
if (GetFlag(n, "explicitcall")) return;
|
||||
|
||||
if (l) {
|
||||
if (SwigType_type(Getattr(l,"type")) == T_VOID) {
|
||||
l = nextSibling(l);
|
||||
|
|
@ -1993,6 +1996,28 @@ class CSHARP : public Language {
|
|||
else
|
||||
Replaceall(tm,"$owner","false");
|
||||
substituteClassname(t, tm);
|
||||
|
||||
// For director methods: generate code to selectively make a normal polymorphic call or
|
||||
// an explicit method call - needed to prevent infinite recursion calls in director methods.
|
||||
Node *explicit_n = Getattr(n,"explicitcallnode");
|
||||
if (explicit_n) {
|
||||
String *ex_overloaded_name = getOverloadedName(explicit_n);
|
||||
String *ex_intermediary_function_name = Swig_name_member(proxy_class_name, ex_overloaded_name);
|
||||
|
||||
String *ex_imcall = Copy(imcall);
|
||||
Replaceall(ex_imcall, intermediary_function_name, ex_intermediary_function_name);
|
||||
|
||||
String *excode = NewString("");
|
||||
if (!Cmp(return_type, "void"))
|
||||
Printf(excode, "if (this.GetType() == typeof(%s)) %s; else %s", proxy_class_name, imcall, ex_imcall);
|
||||
else
|
||||
Printf(excode, "((this.GetType() == typeof(%s)) ? %s : %s)", proxy_class_name, imcall, ex_imcall);
|
||||
|
||||
Clear(imcall);
|
||||
Printv(imcall, excode, NIL);
|
||||
Delete(ex_overloaded_name);
|
||||
Delete(excode);
|
||||
}
|
||||
Replaceall(tm, "$imcall", imcall);
|
||||
excodeSubstitute(n, tm, "csout", n);
|
||||
} else {
|
||||
|
|
@ -3364,6 +3389,22 @@ class CSHARP : public Language {
|
|||
|
||||
Printf(w->code, "}");
|
||||
|
||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||
String *inline_extra_method = NewString("");
|
||||
if (dirprot_mode() && !is_public(n) && !pure_virtual)
|
||||
{
|
||||
Printv(inline_extra_method, declaration, NIL);
|
||||
String *extra_method_name = NewStringf("%sSwigPublic", name);
|
||||
Replaceall(inline_extra_method, name, extra_method_name);
|
||||
Replaceall(inline_extra_method, ";\n", " {\n ");
|
||||
if (!is_void)
|
||||
Printf(inline_extra_method, "return ");
|
||||
String *methodcall = Swig_method_call(super, l);
|
||||
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
|
||||
Delete(methodcall);
|
||||
Delete(extra_method_name);
|
||||
}
|
||||
|
||||
/* emit code */
|
||||
if (status == SWIG_OK && output_director) {
|
||||
if(!is_void) {
|
||||
|
|
@ -3375,6 +3416,7 @@ class CSHARP : public Language {
|
|||
if (!Getattr(n,"defaultargs")) {
|
||||
Wrapper_print(w, f_directors);
|
||||
Printv(f_directors_h, declaration, NIL);
|
||||
Printv(f_directors_h, inline_extra_method, NIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3621,6 +3663,14 @@ class CSHARP : public Language {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* extraDirectorProtectedCPPMethodsRequired()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
bool extraDirectorProtectedCPPMethodsRequired() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Java_director_declaration()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -394,26 +394,15 @@ void emit_action(Node *n, Wrapper *f) {
|
|||
action = Getattr(n,"wrap:action");
|
||||
assert(action != 0);
|
||||
|
||||
if (!(is_public(n)) && is_member_director(n)) {
|
||||
/* We need to add an extra dynamic_cast to
|
||||
access the director class, where the virtual
|
||||
methods are all public */
|
||||
if (!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) {
|
||||
/* In order to call protected virtual director methods from the target language, we need
|
||||
* to add an extra dynamic_cast to call the public C++ wrapper in the director class. */
|
||||
Node* parent = Getattr(n,"parentNode");
|
||||
String* symname = Getattr(parent, "sym:name");
|
||||
String* dirname = NewStringf("SwigDirector_%s", symname);
|
||||
String* dirdecl = NewStringf("%s *darg = 0", dirname);
|
||||
Wrapper_add_local(f, "darg", dirdecl);
|
||||
Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n",dirname);
|
||||
Replace(action, "arg1", "darg", DOH_REPLACE_FIRST);
|
||||
if (Getattr(n,"qualifier")) {
|
||||
/* fix constant casting introduced by a const method decl */
|
||||
String* classtype = Getattr(parent, "classtype");
|
||||
/*
|
||||
String *ccast = NewStringf("((%s const *)darg)",classtype);
|
||||
if (Strstr(action,ccast) != 0)
|
||||
*/
|
||||
Replace(action, classtype, dirname, DOH_REPLACE_FIRST);
|
||||
}
|
||||
Delete(dirname);
|
||||
Delete(dirdecl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1870,6 +1870,9 @@ class JAVA : public Language {
|
|||
// Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
|
||||
if (Getattr(n, "overload:ignore")) return;
|
||||
|
||||
// Don't generate proxy method for additional explicitcall method used in directors
|
||||
if (GetFlag(n, "explicitcall")) return;
|
||||
|
||||
if (l) {
|
||||
if (SwigType_type(Getattr(l,"type")) == T_VOID) {
|
||||
l = nextSibling(l);
|
||||
|
|
@ -1985,6 +1988,29 @@ class JAVA : public Language {
|
|||
else
|
||||
Replaceall(tm,"$owner","false");
|
||||
substituteClassname(t, tm);
|
||||
|
||||
// For director methods: generate code to selectively make a normal polymorphic call or
|
||||
// an explicit method call - needed to prevent infinite recursion calls in director methods.
|
||||
Node *explicit_n = Getattr(n,"explicitcallnode");
|
||||
if (explicit_n) {
|
||||
String *ex_overloaded_name = getOverloadedName(explicit_n);
|
||||
String *ex_intermediary_function_name = Swig_name_member(proxy_class_name, ex_overloaded_name);
|
||||
|
||||
String *ex_imcall = Copy(imcall);
|
||||
Replaceall(ex_imcall, intermediary_function_name, ex_intermediary_function_name);
|
||||
|
||||
String *excode = NewString("");
|
||||
if (!Cmp(return_type, "void"))
|
||||
Printf(excode, "if (getClass() == %s.class) %s; else %s", proxy_class_name, imcall, ex_imcall);
|
||||
else
|
||||
Printf(excode, "(getClass() == %s.class) ? %s : %s", proxy_class_name, imcall, ex_imcall);
|
||||
|
||||
Clear(imcall);
|
||||
Printv(imcall, excode, NIL);
|
||||
Delete(ex_overloaded_name);
|
||||
Delete(excode);
|
||||
}
|
||||
|
||||
Replaceall(tm, "$jnicall", imcall);
|
||||
} else {
|
||||
Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number,
|
||||
|
|
@ -3464,6 +3490,22 @@ class JAVA : public Language {
|
|||
|
||||
Printf(w->code, "}");
|
||||
|
||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||
String *inline_extra_method = NewString("");
|
||||
if (dirprot_mode() && !is_public(n) && !pure_virtual)
|
||||
{
|
||||
Printv(inline_extra_method, declaration, NIL);
|
||||
String *extra_method_name = NewStringf("%sSwigPublic", name);
|
||||
Replaceall(inline_extra_method, name, extra_method_name);
|
||||
Replaceall(inline_extra_method, ";\n", " {\n ");
|
||||
if (!is_void)
|
||||
Printf(inline_extra_method, "return ");
|
||||
String *methodcall = Swig_method_call(super, l);
|
||||
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
|
||||
Delete(methodcall);
|
||||
Delete(extra_method_name);
|
||||
}
|
||||
|
||||
/* emit code */
|
||||
if (status == SWIG_OK && output_director) {
|
||||
if(!is_void) {
|
||||
|
|
@ -3475,9 +3517,11 @@ class JAVA : public Language {
|
|||
if (!Getattr(n,"defaultargs")) {
|
||||
Wrapper_print(w, f_directors);
|
||||
Printv(f_directors_h, declaration, NIL);
|
||||
Printv(f_directors_h, inline_extra_method, NIL);
|
||||
}
|
||||
}
|
||||
|
||||
Delete(inline_extra_method);
|
||||
Delete(qualified_return);
|
||||
Delete(jnidesc);
|
||||
Delete(c_ret_type);
|
||||
|
|
@ -3767,6 +3811,14 @@ class JAVA : public Language {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* extraDirectorProtectedCPPMethodsRequired()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
bool extraDirectorProtectedCPPMethodsRequired() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Java_director_declaration()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ static int InClass = 0; /* Parsing C++ or not */
|
|||
static String *ClassName = 0; /* This is the real name of the current class */
|
||||
static String *ClassPrefix = 0; /* Class prefix */
|
||||
static String *ClassType = 0; /* Fully qualified type name to use */
|
||||
static String *DirectorClassName = 0;/* Director name of the current class */
|
||||
int Abstract = 0;
|
||||
int ImportMode = 0;
|
||||
int IsVirtual = 0;
|
||||
|
|
@ -974,26 +975,27 @@ Language::functionHandler(Node *n) {
|
|||
globalfunctionHandler(n);
|
||||
} else {
|
||||
Node* explicit_n = 0;
|
||||
if (GetFlag(n, "feature:explicitcall")) {
|
||||
// Add in an explicit wrapper call to virtual methods
|
||||
if (Cmp(storage, "virtual") == 0 && (cplus_mode == PUBLIC))
|
||||
explicit_n = Copy(n);
|
||||
if (directorsEnabled() && is_member_director(CurrentClass,n) && !Extend && !extraDirectorProtectedCPPMethodsRequired()) {
|
||||
bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
|
||||
if (virtual_but_not_pure_virtual) {
|
||||
// Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
|
||||
explicit_n = Copy(n);
|
||||
String *new_symname = Copy(Getattr(n,"sym:name"));
|
||||
String *suffix = Getattr(parentNode(n),"sym:name");
|
||||
Printv(new_symname, "SwigExplicit", suffix, NIL);
|
||||
Setattr(explicit_n,"sym:name", new_symname);
|
||||
Delattr(explicit_n,"storage");
|
||||
Delattr(explicit_n,"override");
|
||||
Delattr(explicit_n,"hides");
|
||||
SetFlag(explicit_n,"explicitcall");
|
||||
Setattr(n, "explicitcallnode", explicit_n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memberfunctionHandler(n);
|
||||
|
||||
|
||||
if (explicit_n) {
|
||||
String *new_symname = Copy(Getattr(n,"sym:name"));
|
||||
String *suffix = Getattr(n,"feature:explicitcall:suffix");
|
||||
if (!suffix)
|
||||
suffix = Getattr(parentNode(n),"sym:name");
|
||||
Printv(new_symname, suffix, NIL);
|
||||
Setattr(explicit_n,"sym:name", new_symname);
|
||||
Delattr(explicit_n,"storage");
|
||||
Delattr(explicit_n,"override");
|
||||
Delattr(explicit_n,"hides");
|
||||
SetFlag(explicit_n,"explicitcall");
|
||||
memberfunctionHandler(explicit_n);
|
||||
memberfunctionHandler(explicit_n);
|
||||
Delattr(explicit_n,"explicitcall");
|
||||
Delete(explicit_n);
|
||||
}
|
||||
|
|
@ -1149,12 +1151,31 @@ Language::memberfunctionHandler(Node *n) {
|
|||
Setattr(n,"classname",Getattr(CurrentClass,"allocate:smartpointerbase"));
|
||||
}
|
||||
}
|
||||
/* Transformation */
|
||||
Swig_MethodToFunction(n,ClassType, Getattr(n,"template") ? 0 : Extend | SmartPointer);
|
||||
|
||||
// Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
|
||||
// Note: protected director methods only.
|
||||
String* director_type = 0;
|
||||
if (!is_public(n) && (is_member_director(CurrentClass,n) || GetFlag(n, "explicitcall"))) {
|
||||
director_type = Copy(DirectorClassName);
|
||||
String *qualifier = Getattr(n,k_qualifier);
|
||||
if (qualifier)
|
||||
SwigType_push(director_type,qualifier);
|
||||
SwigType_add_pointer(director_type);
|
||||
}
|
||||
|
||||
int DirectorExtraCall = 0;
|
||||
if (directorsEnabled() && is_member_director(CurrentClass,n) && !SmartPointer)
|
||||
if (extraDirectorProtectedCPPMethodsRequired())
|
||||
DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
|
||||
|
||||
if (GetFlag(n, "explicitcall"))
|
||||
DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
|
||||
|
||||
Swig_MethodToFunction(n, ClassType, Getattr(n,"template") ? 0 : Extend | SmartPointer | DirectorExtraCall, director_type, is_member_director(CurrentClass,n));
|
||||
Setattr(n,"sym:name",fname);
|
||||
functionWrapper(n);
|
||||
|
||||
/* DelWrapper(w);*/
|
||||
Delete(director_type);
|
||||
Delete(fname);
|
||||
Swig_restore(n);
|
||||
return SWIG_OK;
|
||||
|
|
@ -1970,15 +1991,13 @@ int Language::classDirectorDestructor(Node *n) {
|
|||
*/
|
||||
File *f_directors = Swig_filebyname("director");
|
||||
File *f_directors_h = Swig_filebyname("director_h");
|
||||
String *classname= Swig_class_name(getCurrentClass());
|
||||
if (Getattr(n,"throw")) {
|
||||
Printf(f_directors_h, " virtual ~SwigDirector_%s() throw ();\n", classname);
|
||||
Printf(f_directors, "SwigDirector_%s::~SwigDirector_%s() throw () {\n}\n\n", classname, classname);
|
||||
Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName);
|
||||
Printf(f_directors, "%s::~%s() throw () {\n}\n\n", DirectorClassName, DirectorClassName);
|
||||
} else {
|
||||
Printf(f_directors_h, " virtual ~SwigDirector_%s();\n", classname);
|
||||
Printf(f_directors, "SwigDirector_%s::~SwigDirector_%s() {\n}\n\n", classname, classname);
|
||||
Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
|
||||
Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
|
||||
}
|
||||
Delete(classname);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2290,6 +2309,7 @@ int Language::classDeclaration(Node *n) {
|
|||
}
|
||||
|
||||
if (dir) {
|
||||
DirectorClassName = NewStringf("SwigDirector_%s", symname);
|
||||
classDirector(n);
|
||||
}
|
||||
/* check for abstract after resolving directors */
|
||||
|
|
@ -2306,6 +2326,7 @@ int Language::classDeclaration(Node *n) {
|
|||
Delete(ClassType); ClassType = 0;
|
||||
Delete(ClassPrefix); ClassPrefix = 0;
|
||||
Delete(ClassName); ClassName = 0;
|
||||
Delete(DirectorClassName); DirectorClassName = 0;
|
||||
Swig_restore(n);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -2340,6 +2361,35 @@ int Language::classHandler(Node *n) {
|
|||
/* emit director disown method */
|
||||
if (hasDirector) {
|
||||
classDirectorDisown(n);
|
||||
|
||||
/* Emit additional protected virtual methods - only needed if the language module
|
||||
* codes logic in the C++ layer instead of the director proxy class method - primarily
|
||||
* to catch public use of protected methods by the sripting languages. */
|
||||
if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
|
||||
Node *vtable = Getattr(n, "vtable");
|
||||
String* symname = Getattr(n, "sym:name");
|
||||
Node *item;
|
||||
Iterator k;
|
||||
AccessMode old_mode = cplus_mode;
|
||||
cplus_mode = PROTECTED;
|
||||
for (k = First(vtable); k.key; k = Next(k)) {
|
||||
item = k.item;
|
||||
Node *method = Getattr(item, "methodNode");
|
||||
SwigType *type = Getattr(method,"nodeType");
|
||||
if (Strcmp(type,"cdecl") !=0 ) continue;
|
||||
String* methodname = Getattr(method,"sym:name");
|
||||
String* wrapname = NewStringf("%s_%s", symname,methodname);
|
||||
if (!Getattr(symbols,wrapname) && (!is_public(method))) {
|
||||
Node* m = Copy(method);
|
||||
Setattr(m, "director", "1");
|
||||
Setattr(m,"parentNode", n);
|
||||
cDeclaration(m);
|
||||
Delete(m);
|
||||
}
|
||||
Delete(wrapname);
|
||||
}
|
||||
cplus_mode = old_mode;
|
||||
}
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
|
|
@ -3049,7 +3099,7 @@ int Language::need_nonpublic_member(Node *n)
|
|||
needed. */
|
||||
return 1;
|
||||
} else {
|
||||
/* if the method is pure virtual, we needed it. */
|
||||
/* if the method is pure virtual, we need it. */
|
||||
int pure_virtual = (Cmp(Getattr(n,"value"),"0") == 0);
|
||||
return pure_virtual;
|
||||
}
|
||||
|
|
@ -3067,6 +3117,14 @@ int Language::is_smart_pointer() const {
|
|||
return SmartPointer;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::extraDirectorProtectedCPPMethodsRequired()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
bool Language::extraDirectorProtectedCPPMethodsRequired() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::is_wrapping_class()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -448,6 +448,7 @@ public:
|
|||
SwigType *d = Getattr(n,"type");
|
||||
String *return_type_normalized = normalizeTemplatedClassName(d);
|
||||
ParmList *l = Getattr(n,"parms");
|
||||
int director_method = 0;
|
||||
Parm *p;
|
||||
|
||||
Wrapper *f = NewWrapper();
|
||||
|
|
@ -465,10 +466,7 @@ public:
|
|||
int numreq;
|
||||
int newobj = GetFlag(n,"feature:new");
|
||||
String *nodeType = Getattr(n, "nodeType");
|
||||
int constructor = !Cmp(nodeType, "constructor");
|
||||
int destructor = (!Cmp(nodeType, "destructor"));
|
||||
String *storage = Getattr(n,"storage");
|
||||
int isVirtual = !Cmp(storage,"virtual");
|
||||
String *overname = 0;
|
||||
bool isOverloaded = Getattr(n,"sym:overloaded") ? true : false;
|
||||
|
||||
|
|
@ -687,18 +685,12 @@ public:
|
|||
// (the smart-pointer) and the director object (the "pointee") are
|
||||
// distinct.
|
||||
|
||||
if (directorsEnabled()) {
|
||||
if (!is_smart_pointer()) {
|
||||
if (/*directorbase &&*/ !constructor && !destructor
|
||||
&& isVirtual && !Getattr(n,"feature:nodirector")) {
|
||||
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
|
||||
Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
|
||||
|
||||
Printf(f->code,
|
||||
"if (director && !director->swig_get_up(false))"
|
||||
"director->swig_set_up();\n");
|
||||
}
|
||||
}
|
||||
director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
|
||||
if (director_method) {
|
||||
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
|
||||
Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
|
||||
Wrapper_add_local(f, "upcall", "bool upcall = false");
|
||||
Append(f->code, "upcall = (director);\n");
|
||||
}
|
||||
|
||||
// Now write code to make the function call
|
||||
|
|
@ -1665,17 +1657,6 @@ public:
|
|||
Printv(w->code, "swig_result = Val_unit;\n",0);
|
||||
Printf(w->code,"args = Val_unit;\n");
|
||||
|
||||
/* direct call to superclass if _up is set */
|
||||
if( pure_virtual ) {
|
||||
Printf(w->code, "if (swig_get_up()) {\n");
|
||||
Printf(w->code, " throw Swig::DirectorPureVirtualException();\n");
|
||||
Printf(w->code, "}\n");
|
||||
} else {
|
||||
Printf(w->code, "if (swig_get_up()) {\n");
|
||||
Printf(w->code, "CAMLreturn(%s);\n", Swig_method_call(super,l));
|
||||
Printf(w->code, "}\n");
|
||||
}
|
||||
|
||||
/* wrap complex arguments to values */
|
||||
Printv(w->code, wrap_args, NIL);
|
||||
|
||||
|
|
@ -1778,11 +1759,28 @@ public:
|
|||
|
||||
Printf(w->code, "}\n");
|
||||
|
||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||
String *inline_extra_method = NewString("");
|
||||
if (dirprot_mode() && !is_public(n) && !pure_virtual)
|
||||
{
|
||||
Printv(inline_extra_method, declaration, NIL);
|
||||
String *extra_method_name = NewStringf("%sSwigPublic", name);
|
||||
Replaceall(inline_extra_method, name, extra_method_name);
|
||||
Replaceall(inline_extra_method, ";\n", " {\n ");
|
||||
if (!is_void)
|
||||
Printf(inline_extra_method, "return ");
|
||||
String *methodcall = Swig_method_call(super, l);
|
||||
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
|
||||
Delete(methodcall);
|
||||
Delete(extra_method_name);
|
||||
}
|
||||
|
||||
/* emit the director method */
|
||||
if (status == SWIG_OK) {
|
||||
if (!Getattr(n,"defaultargs")) {
|
||||
Wrapper_print(w, f_directors);
|
||||
Printv(f_directors_h, declaration, NIL);
|
||||
Printv(f_directors_h, inline_extra_method, NIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1612,7 +1612,6 @@ public:
|
|||
int constructor = (!Cmp(nodeType, "constructor"));
|
||||
int destructor = (!Cmp(nodeType, "destructor"));
|
||||
String *storage = Getattr(n,"storage");
|
||||
int isVirtual = (Cmp(storage,"virtual") == 0);
|
||||
/* Only the first constructor is handled as init method. Others
|
||||
constructor can be emitted via %rename */
|
||||
int handled_as_init = 0;
|
||||
|
|
@ -1946,25 +1945,21 @@ public:
|
|||
// (the smart-pointer) and the director object (the "pointee") are
|
||||
// distinct.
|
||||
|
||||
if (directorsEnabled()) {
|
||||
if (!is_smart_pointer()) {
|
||||
if (/*directorbase &&*/ !constructor && !destructor
|
||||
&& isVirtual && !Getattr(n,"feature:nodirector")) {
|
||||
director_method = 1;
|
||||
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
|
||||
Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
|
||||
if (dirprot_mode() && !is_public(n)) {
|
||||
Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name);
|
||||
Printf(f->code, "SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing protected member %s\");\n", name);
|
||||
Append(f->code, "SWIG_fail;\n");
|
||||
Append(f->code, "}\n");
|
||||
}
|
||||
if (funpack) {
|
||||
Append(f->code, "if (director && (director->swig_get_self()==swig_obj[0])) director->swig_set_up();\n");
|
||||
} else {
|
||||
Append(f->code, "if (director && (director->swig_get_self()==obj0)) director->swig_set_up();\n");
|
||||
}
|
||||
}
|
||||
director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
|
||||
if (director_method) {
|
||||
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
|
||||
Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
|
||||
if (dirprot_mode() && !is_public(n)) {
|
||||
Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name);
|
||||
Printf(f->code, "SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing protected member %s\");\n", name);
|
||||
Append(f->code, "SWIG_fail;\n");
|
||||
Append(f->code, "}\n");
|
||||
}
|
||||
Wrapper_add_local(f, "upcall", "bool upcall = false");
|
||||
if (funpack) {
|
||||
Append(f->code, "upcall = (director && (director->swig_get_self()==swig_obj[0]));\n");
|
||||
} else {
|
||||
Append(f->code, "upcall = (director && (director->swig_get_self()==obj0));\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3570,29 +3565,12 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
|
|||
p = nextSibling(p);
|
||||
}
|
||||
|
||||
|
||||
/* add the method name as a PyString */
|
||||
/* add the method name as a PyString */
|
||||
String *pyname = Getattr(n,"sym:name");
|
||||
|
||||
int allow_thread = threads_enable(n);
|
||||
|
||||
/* direct call to superclass if _up is set */
|
||||
if (allow_thread) thread_begin_block(n, w->code);
|
||||
Append(w->code, "if (swig_get_up()) {\n");
|
||||
if (pure_virtual) {
|
||||
Printf(w->code,
|
||||
"Swig::DirectorPureVirtualException::raise(\"%s.\");\n",Swig_method_call(super,l));
|
||||
} else {
|
||||
if (allow_thread) thread_begin_allow(n, w->code);
|
||||
if (is_void) {
|
||||
Printf(w->code, "%s;\n", Swig_method_call(super,l));
|
||||
Append(w->code, "return;\n");
|
||||
} else {
|
||||
Printf(w->code, "return %s;\n", Swig_method_call(super,l));
|
||||
}
|
||||
if (allow_thread) thread_end_allow(n, w->code);
|
||||
}
|
||||
Append(w->code, "}\n");
|
||||
|
||||
/* declare method return value
|
||||
* if the return value is a reference or const reference, a specialized typemap must
|
||||
|
|
@ -3784,11 +3762,28 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
|
|||
}
|
||||
Append(w->code, "}\n");
|
||||
|
||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||
String *inline_extra_method = NewString("");
|
||||
if (dirprot_mode() && !is_public(n) && !pure_virtual)
|
||||
{
|
||||
Printv(inline_extra_method, declaration, NIL);
|
||||
String *extra_method_name = NewStringf("%sSwigPublic", name);
|
||||
Replaceall(inline_extra_method, name, extra_method_name);
|
||||
Replaceall(inline_extra_method, ";\n", " {\n ");
|
||||
if (!is_void)
|
||||
Printf(inline_extra_method, "return ");
|
||||
String *methodcall = Swig_method_call(super, l);
|
||||
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
|
||||
Delete(methodcall);
|
||||
Delete(extra_method_name);
|
||||
}
|
||||
|
||||
/* emit the director method */
|
||||
if (status == SWIG_OK) {
|
||||
if (!Getattr(n,"defaultargs")) {
|
||||
Wrapper_print(w, f_directors);
|
||||
Printv(f_directors_h, declaration, NIL);
|
||||
Printv(f_directors_h, inline_extra_method, NIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -991,7 +991,6 @@ public:
|
|||
bool constructor;
|
||||
bool destructor;
|
||||
String *storage;
|
||||
bool isVirtual;
|
||||
|
||||
String *symname = Copy(Getattr(n,"sym:name"));
|
||||
SwigType *t = Getattr(n,"type");
|
||||
|
|
@ -1009,7 +1008,6 @@ public:
|
|||
constructor = (!Cmp(nodeType, "constructor"));
|
||||
destructor = (!Cmp(nodeType, "destructor"));
|
||||
storage = Getattr(n, "storage");
|
||||
isVirtual = (Cmp(storage, "virtual") == 0);
|
||||
|
||||
/* If the C++ class constructor is overloaded, we only want to
|
||||
* write out the "new" singleton method once since it is always
|
||||
|
|
@ -1135,16 +1133,12 @@ public:
|
|||
// (the smart-pointer) and the director object (the "pointee") are
|
||||
// distinct.
|
||||
|
||||
if (directorsEnabled()) {
|
||||
if (!is_smart_pointer()) {
|
||||
if (/*directorbase &&*/ !constructor && !destructor
|
||||
&& isVirtual && !Getattr(n,"feature:nodirector")) {
|
||||
director_method = 1;
|
||||
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
|
||||
Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
|
||||
Printf(f->code, "if (director && (director->swig_get_self() == self)) director->swig_set_up();\n");
|
||||
}
|
||||
}
|
||||
director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
|
||||
if (director_method) {
|
||||
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
|
||||
Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
|
||||
Wrapper_add_local(f, "upcall", "bool upcall = false");
|
||||
Append(f->code, "upcall = (director && (director->swig_get_self() == self));\n");
|
||||
}
|
||||
|
||||
/* Now write code to make the function call */
|
||||
|
|
@ -2484,20 +2478,6 @@ public:
|
|||
/* declare Ruby return value */
|
||||
Wrapper_add_local(w, "result", "VALUE result");
|
||||
|
||||
/* direct call to superclass if _up is set */
|
||||
Printf(w->code, "if (swig_get_up()) {\n");
|
||||
if (pure_virtual) {
|
||||
Printf(w->code, "throw Swig::DirectorPureVirtualException();\n");
|
||||
} else {
|
||||
if (is_void) {
|
||||
Printf(w->code, "%s;\n", Swig_method_call(super,l));
|
||||
Printf(w->code, "return;\n");
|
||||
} else {
|
||||
Printf(w->code, "return %s;\n", Swig_method_call(super,l));
|
||||
}
|
||||
}
|
||||
Printf(w->code, "}\n");
|
||||
|
||||
/* wrap complex arguments to VALUEs */
|
||||
Printv(w->code, wrap_args, NIL);
|
||||
|
||||
|
|
@ -2588,14 +2568,30 @@ public:
|
|||
}
|
||||
Delete(rettype);
|
||||
}
|
||||
|
||||
Printf(w->code, "}\n");
|
||||
|
||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||
String *inline_extra_method = NewString("");
|
||||
if (dirprot_mode() && !is_public(n) && !pure_virtual)
|
||||
{
|
||||
Printv(inline_extra_method, declaration, NIL);
|
||||
String *extra_method_name = NewStringf("%sSwigPublic", name);
|
||||
Replaceall(inline_extra_method, name, extra_method_name);
|
||||
Replaceall(inline_extra_method, ";\n", " {\n ");
|
||||
if (!is_void)
|
||||
Printf(inline_extra_method, "return ");
|
||||
String *methodcall = Swig_method_call(super, l);
|
||||
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
|
||||
Delete(methodcall);
|
||||
Delete(extra_method_name);
|
||||
}
|
||||
|
||||
/* emit the director method */
|
||||
if (status == SWIG_OK) {
|
||||
if (!Getattr(n,"defaultargs")) {
|
||||
Wrapper_print(w, f_directors);
|
||||
Printv(f_directors_h, declaration, NIL);
|
||||
Printv(f_directors_h, inline_extra_method, NIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,9 @@ protected:
|
|||
/* Return true if the current method is part of a smart-pointer */
|
||||
int is_smart_pointer() const;
|
||||
|
||||
/* Some language modules require additional wrappers for virtual methods not declared in sub-classes */
|
||||
virtual bool extraDirectorProtectedCPPMethodsRequired() const;
|
||||
|
||||
/* Director subclass comparison test */
|
||||
String *none_comparison;
|
||||
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ Swig_cfunction_call(String_or_char *name, ParmList *parms) {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static String *
|
||||
Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self, String *explicit_qualifier) {
|
||||
Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self, String *explicit_qualifier, SwigType *director_type) {
|
||||
String *func, *nname;
|
||||
int i = 0;
|
||||
Parm *p = parms;
|
||||
|
|
@ -402,36 +402,44 @@ Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self, S
|
|||
} else {
|
||||
nname = SwigType_namestr(name);
|
||||
}
|
||||
|
||||
pt = Getattr(p,k_type);
|
||||
|
||||
/* If the method is invoked through a dereferenced pointer, we don't add any casts
|
||||
(needed for smart pointers). Otherwise, we cast to the appropriate type */
|
||||
|
||||
if (Strstr(func,"*this")) {
|
||||
String *pname = Swig_cparm_name(p,0);
|
||||
Replaceall(func,"this", pname);
|
||||
Delete(pname);
|
||||
} else {
|
||||
String *pname = Swig_cparm_name(p,0);
|
||||
String *rcaststr = SwigType_rcaststr(pt, pname);
|
||||
if (director_type) {
|
||||
const char *pname = "darg";
|
||||
String *rcaststr = SwigType_rcaststr(director_type, pname);
|
||||
Replaceall(func,"this", rcaststr);
|
||||
Delete(rcaststr);
|
||||
Delete(pname);
|
||||
} else {
|
||||
pt = Getattr(p,k_type);
|
||||
|
||||
/* If the method is invoked through a dereferenced pointer, we don't add any casts
|
||||
(needed for smart pointers). Otherwise, we cast to the appropriate type */
|
||||
|
||||
if (Strstr(func,"*this")) {
|
||||
String *pname = Swig_cparm_name(p,0);
|
||||
Replaceall(func,"this", pname);
|
||||
Delete(pname);
|
||||
} else {
|
||||
String *pname = Swig_cparm_name(p,0);
|
||||
String *rcaststr = SwigType_rcaststr(pt, pname);
|
||||
Replaceall(func,"this", rcaststr);
|
||||
Delete(rcaststr);
|
||||
Delete(pname);
|
||||
}
|
||||
|
||||
/*
|
||||
SWIGTEMPLATEDESIMBUAGATOR is compiler dependent (swiglabels.swg),
|
||||
- SUN Studio 9 requires 'template',
|
||||
- gcc-3.4 forbids the use of 'template' (correctly implementing the ISO C++ standard)
|
||||
the others don't seem to care,
|
||||
*/
|
||||
if (SwigType_istemplate(name))
|
||||
Printf(func,"SWIGTEMPLATEDISAMBIGUATOR ");
|
||||
|
||||
if (explicit_qualifier) {
|
||||
Printv(func, explicit_qualifier, "::", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
SWIGTEMPLATEDESIMBUAGATOR is compiler dependent (swiglabels.swg),
|
||||
- SUN Studio 9 requires 'template',
|
||||
- gcc-3.4 forbids the use of 'template'.
|
||||
the rest seems not caring very much,
|
||||
*/
|
||||
if (SwigType_istemplate(name))
|
||||
Printf(func,"SWIGTEMPLATEDISAMBIGUATOR ");
|
||||
|
||||
if (explicit_qualifier)
|
||||
Printv(func, explicit_qualifier, "::", NIL);
|
||||
|
||||
Printf(func,"%s(", nname);
|
||||
|
||||
i++;
|
||||
|
|
@ -787,7 +795,7 @@ Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms,
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
Swig_MethodToFunction(Node *n, String *classname, int flags) {
|
||||
Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director) {
|
||||
String *name, *qualifier;
|
||||
ParmList *parms;
|
||||
SwigType *type;
|
||||
|
|
@ -845,13 +853,51 @@ Swig_MethodToFunction(Node *n, String *classname, int flags) {
|
|||
|
||||
/* Generate action code for the access */
|
||||
if (!(flags & CWRAP_EXTEND)) {
|
||||
/* Call the explicit method rather than allow for a polymorphic call */
|
||||
String *explicit_qualifier = GetFlag(n,"explicitcall") ?
|
||||
SwigType_namestr(Getattr(Getattr(parentNode(n),"typescope"),k_qname)) : 0;
|
||||
String *explicit_qualifier = 0;
|
||||
String *call = 0;
|
||||
String *cres = 0;
|
||||
String *explicitcall_name = 0;
|
||||
int pure_virtual = !(Cmp(Getattr(n,k_storage), "virtual")) && !(Cmp(Getattr(n,k_value), "0"));
|
||||
|
||||
String *call = Swig_cmethod_call(name,p,self,explicit_qualifier);
|
||||
String *cres = Swig_cresult(Getattr(n,k_type),k_result, call);
|
||||
Setattr(n,k_wrapaction, cres);
|
||||
/* Call the explicit method rather than allow for a polymorphic call */
|
||||
if ((flags & CWRAP_DIRECTOR_TWO_CALLS) || (flags & CWRAP_DIRECTOR_ONE_CALL)) {
|
||||
String* access = Getattr(n, "access");
|
||||
if (access && (Cmp(access, "protected") == 0)) {
|
||||
/* If protected access (can only be if a director method) then call the extra public accessor method (language module must provide this) */
|
||||
String *explicit_qualifier_tmp = SwigType_namestr(Getattr(Getattr(parentNode(n),"typescope"),k_qname));
|
||||
explicitcall_name = NewStringf("%sSwigPublic", name);
|
||||
explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp);
|
||||
Delete(explicit_qualifier_tmp);
|
||||
} else {
|
||||
explicit_qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n),"typescope"),k_qname));
|
||||
}
|
||||
}
|
||||
|
||||
call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type);
|
||||
cres = Swig_cresult(Getattr(n,k_type),k_result, call);
|
||||
|
||||
if (pure_virtual && is_director && (flags & CWRAP_DIRECTOR_TWO_CALLS)) {
|
||||
String *qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n),"typescope"),k_qname));
|
||||
Delete(cres);
|
||||
cres = NewStringf("Swig::DirectorPureVirtualException::raise(\"%s::%s\");", qualifier, name);
|
||||
Delete(qualifier);
|
||||
}
|
||||
|
||||
if (flags & CWRAP_DIRECTOR_TWO_CALLS) {
|
||||
/* Create two method calls, one to call the explicit method, the other a normal polymorphic function call */
|
||||
String *cres_both_calls = NewStringf("");
|
||||
String *call_extra = Swig_cmethod_call(name, p, self, 0, director_type);
|
||||
String *cres_extra = Swig_cresult(Getattr(n,k_type),k_result, call_extra);
|
||||
Printv(cres_both_calls, "if (upcall) {\n", cres, "\n", "} else {", cres_extra, "\n}", NIL);
|
||||
Setattr(n,k_wrapaction, cres_both_calls);
|
||||
Delete(cres_extra);
|
||||
Delete(call_extra);
|
||||
Delete(cres_both_calls);
|
||||
} else {
|
||||
Setattr(n,k_wrapaction, cres);
|
||||
}
|
||||
|
||||
Delete(explicitcall_name);
|
||||
Delete(call);
|
||||
Delete(cres);
|
||||
Delete(explicit_qualifier);
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ extern int Swig_add_extension_code(Node *n, const String *function_name,
|
|||
|
||||
/* --- Transformations --- */
|
||||
|
||||
extern int Swig_MethodToFunction(Node *n, String *classname, int flags);
|
||||
extern int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director);
|
||||
extern int Swig_ConstructorToFunction(Node *n, String *classname,
|
||||
String *none_comparison,
|
||||
String *director_ctor,
|
||||
|
|
@ -508,6 +508,8 @@ extern int Swig_VarsetToFunction(Node *n, int flags);
|
|||
#define CWRAP_EXTEND 0x01
|
||||
#define CWRAP_SMART_POINTER 0x02
|
||||
#define CWRAP_NATURAL_VAR 0x04
|
||||
#define CWRAP_DIRECTOR_ONE_CALL 0x08
|
||||
#define CWRAP_DIRECTOR_TWO_CALLS 0x10
|
||||
|
||||
/* --- Director Helpers --- */
|
||||
extern Node *Swig_methodclass(Node *n);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue