Directors are output in the order in which they are declared in the C++ class rather than in some pseudo-random order.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9391 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
ccf9423225
commit
79eb884747
1 changed files with 42 additions and 41 deletions
|
|
@ -1710,7 +1710,7 @@ String *vtable_method_id(Node *n)
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
int Language::unrollVirtualMethods(Node *n,
|
int Language::unrollVirtualMethods(Node *n,
|
||||||
Node *parent,
|
Node *parent,
|
||||||
Hash *vm,
|
List *vm,
|
||||||
int default_director,
|
int default_director,
|
||||||
int &virtual_destructor,
|
int &virtual_destructor,
|
||||||
int protectedbase) {
|
int protectedbase) {
|
||||||
|
|
@ -1750,20 +1750,21 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
if ((Cmp(nodeType, "cdecl") == 0)|| is_destructor) {
|
if ((Cmp(nodeType, "cdecl") == 0)|| is_destructor) {
|
||||||
decl = Getattr(ni, "decl");
|
decl = Getattr(ni, "decl");
|
||||||
/* extra check for function type and proper access */
|
/* extra check for function type and proper access */
|
||||||
if (SwigType_isfunction(decl)
|
if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(ni)) || need_nonpublic_member(ni))) {
|
||||||
&& (((!protectedbase || dirprot_mode()) && is_public(ni))
|
|
||||||
|| need_nonpublic_member(ni))) {
|
|
||||||
String *name = Getattr(ni, "name");
|
String *name = Getattr(ni, "name");
|
||||||
Node *method_id = is_destructor ?
|
Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(ni);
|
||||||
NewStringf("~destructor") : vtable_method_id(ni);
|
|
||||||
/* Make sure that the new method overwrites the existing: */
|
/* Make sure that the new method overwrites the existing: */
|
||||||
Hash *exists_item = Getattr(vm, method_id);
|
int len = Len(vm);
|
||||||
if (exists_item) {
|
const int DO_NOT_REPLACE = -1;
|
||||||
/* maybe we should check for precedence here, ie, only
|
int replace = DO_NOT_REPLACE;
|
||||||
delete the previous method if 'n' is derived from the
|
for (int i=0; i<len; i++) {
|
||||||
previous method parent node. This is almost always true,
|
Node *item = Getitem(vm,i);
|
||||||
so by now, we just delete the entry. */
|
String *check_vmid = Getattr(item, "vmid");
|
||||||
Delattr(vm, method_id);
|
|
||||||
|
if (Strcmp(method_id, check_vmid) == 0) {
|
||||||
|
replace = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* filling a new method item */
|
/* filling a new method item */
|
||||||
String *fqdname = NewStringf("%s::%s", classname, name);
|
String *fqdname = NewStringf("%s::%s", classname, name);
|
||||||
|
|
@ -1784,11 +1785,13 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
/* apply the features of the original method found in the base class */
|
/* apply the features of the original method found in the base class */
|
||||||
Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m,"decl"), m);
|
Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m,"decl"), m);
|
||||||
Setattr(item, "methodNode", m);
|
Setattr(item, "methodNode", m);
|
||||||
Setattr(vm, method_id, item);
|
Setattr(item, "vmid", method_id);
|
||||||
|
if (replace == DO_NOT_REPLACE)
|
||||||
|
Append(vm, item);
|
||||||
|
else
|
||||||
|
Setitem(vm, replace, item);
|
||||||
|
|
||||||
Delete(mname);
|
Delete(mname);
|
||||||
Delete(fqdname);
|
|
||||||
Delete(item);
|
|
||||||
Delete(method_id);
|
|
||||||
}
|
}
|
||||||
if (is_destructor) {
|
if (is_destructor) {
|
||||||
virtual_destructor = 1;
|
virtual_destructor = 1;
|
||||||
|
|
@ -1804,9 +1807,10 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
an the recursive loop!.
|
an the recursive loop!.
|
||||||
*/
|
*/
|
||||||
if (n == parent) {
|
if (n == parent) {
|
||||||
Iterator k;
|
int len = Len(vm);
|
||||||
for (k = First(vm); k.key; k = Next(k)) {
|
for (int i=0; i<len; i++) {
|
||||||
Node *m = Getattr(k.item, "methodNode");
|
Node *item = Getitem(vm,i);
|
||||||
|
Node *m = Getattr(item, "methodNode");
|
||||||
/* retrieve the director features */
|
/* retrieve the director features */
|
||||||
int mdir = GetFlag(m, "feature:director");
|
int mdir = GetFlag(m, "feature:director");
|
||||||
int mndir = GetFlag(m, "feature:nodirector");
|
int mndir = GetFlag(m, "feature:nodirector");
|
||||||
|
|
@ -1827,7 +1831,7 @@ int Language::unrollVirtualMethods(Node *n,
|
||||||
if (mndir) Delattr(m, "feature:nodirector");
|
if (mndir) Delattr(m, "feature:nodirector");
|
||||||
} else {
|
} else {
|
||||||
/* or just delete from the vm, since is not a director method */
|
/* or just delete from the vm, since is not a director method */
|
||||||
Delattr(vm, k.key);
|
Delitem(vm, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1947,15 +1951,12 @@ int Language::classDirectorConstructors(Node *n) {
|
||||||
|
|
||||||
int Language::classDirectorMethods(Node *n) {
|
int Language::classDirectorMethods(Node *n) {
|
||||||
Node *vtable = Getattr(n, "vtable");
|
Node *vtable = Getattr(n, "vtable");
|
||||||
Node *item;
|
|
||||||
Iterator k;
|
|
||||||
|
|
||||||
for (k = First(vtable); k.key; k = Next(k)) {
|
int len = Len(vtable);
|
||||||
item = k.item;
|
for (int i=0; i<len; i++) {
|
||||||
|
Node *item = Getitem(vtable,i);
|
||||||
String *method = Getattr(item, "methodNode");
|
String *method = Getattr(item, "methodNode");
|
||||||
String *fqdname = Getattr(item, "fqdname");
|
String *fqdname = Getattr(item, "fqdname");
|
||||||
// if (GetFlag(method,"feature:ignore"))
|
|
||||||
// continue;
|
|
||||||
if (GetFlag(method, "feature:nodirector"))
|
if (GetFlag(method, "feature:nodirector"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -2027,7 +2028,7 @@ int Language::classDirector(Node *n) {
|
||||||
Setattr(module, "wrap:directormap", directormap);
|
Setattr(module, "wrap:directormap", directormap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Hash* vtable = NewHash();
|
List* vtable = NewList();
|
||||||
int virtual_destructor = 0;
|
int virtual_destructor = 0;
|
||||||
unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
|
unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
|
||||||
if (virtual_destructor || Len(vtable) > 0) {
|
if (virtual_destructor || Len(vtable) > 0) {
|
||||||
|
|
@ -2366,16 +2367,15 @@ int Language::classHandler(Node *n) {
|
||||||
|
|
||||||
/* Emit additional protected virtual methods - only needed if the language module
|
/* 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
|
* 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. */
|
* to catch public use of protected methods by the scripting languages. */
|
||||||
if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
|
if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
|
||||||
Node *vtable = Getattr(n, "vtable");
|
Node *vtable = Getattr(n, "vtable");
|
||||||
String* symname = Getattr(n, "sym:name");
|
String* symname = Getattr(n, "sym:name");
|
||||||
Node *item;
|
|
||||||
Iterator k;
|
|
||||||
AccessMode old_mode = cplus_mode;
|
AccessMode old_mode = cplus_mode;
|
||||||
cplus_mode = PROTECTED;
|
cplus_mode = PROTECTED;
|
||||||
for (k = First(vtable); k.key; k = Next(k)) {
|
int len = Len(vtable);
|
||||||
item = k.item;
|
for (int i=0; i<len; i++) {
|
||||||
|
Node *item = Getitem(vtable,i);
|
||||||
Node *method = Getattr(item, "methodNode");
|
Node *method = Getattr(item, "methodNode");
|
||||||
SwigType *type = Getattr(method,"nodeType");
|
SwigType *type = Getattr(method,"nodeType");
|
||||||
if (Strcmp(type,"cdecl") !=0 )
|
if (Strcmp(type,"cdecl") !=0 )
|
||||||
|
|
@ -3200,14 +3200,15 @@ int Language::abstractClassTest(Node *n) {
|
||||||
Node *ni = Getitem(abstract,i);
|
Node *ni = Getitem(abstract,i);
|
||||||
Node *method_id = vtable_method_id(ni);
|
Node *method_id = vtable_method_id(ni);
|
||||||
if (!method_id) continue;
|
if (!method_id) continue;
|
||||||
Hash *exists_item = Getattr(vtable, method_id);
|
bool exists_item = false;
|
||||||
#ifdef SWIG_DEBUG
|
int len = Len(vtable);
|
||||||
Printf(stderr,"method %s %d\n",method_id,exists_item ? 1 : 0);
|
for (int i=0; i<len; i++) {
|
||||||
#endif
|
Node *item = Getitem(vtable,i);
|
||||||
Delete(method_id);
|
String *check_item = Getattr(item, "vmid");
|
||||||
if (!exists_item) {
|
if (Strcmp(method_id, check_item) == 0) {
|
||||||
dirabstract = ni;
|
exists_item = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dirabstract) {
|
if (dirabstract) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue