partial fix for abstract director classes

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4534 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Mark Rose 2003-03-14 07:14:04 +00:00
commit d0f9431db8
5 changed files with 50 additions and 14 deletions

View file

@ -1378,6 +1378,19 @@ int Language::unrollVirtualMethods(Node *n,
if (Getattr(n, "feature:director")) default_director = 1;
if (Getattr(n, "feature:nodirector")) default_director = -1;
}
// recurse through all base classes to build the vtable
List* bl = Getattr(n, "bases");
if (bl) {
Node* bi;
for (bi = Firstitem(bl); bi; bi = Nextitem(bl)) {
int virtual_base = 0;
unrollVirtualMethods(bi, parent, vm, default_director, virtual_destructor, virtual_base);
if (virtual_base) {
has_virtual = 1;
}
}
}
// find the methods that need directors
classname = Getattr(n, "name");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
nodeType = Getattr(ni, "nodeType");
@ -1397,7 +1410,16 @@ int Language::unrollVirtualMethods(Node *n,
if (Getattr(ni, "feature:director")) director = 1;
if (Getattr(ni, "feature:nodirector")) director = 0;
}
if ((director == 1) && !Getattr(vm, method_id)) {
// if this method has a director in a base class, we must
// either override it or remove it (otherwise the director
// method will use the wrong class for superclass calls)
if (Getattr(vm, method_id)) {
if (director == 0) director = 1;
else if (director < 0) {
Delattr(vm, method_id);
}
}
if (director == 1) {
String *fqname = NewString("");
Printf(fqname, "%s::%s", classname, name);
Hash *item = NewHash();
@ -1419,17 +1441,6 @@ int Language::unrollVirtualMethods(Node *n,
else {
}
}
List* bl = Getattr(n, "bases");
if (bl) {
Node* bi;
for (bi = Firstitem(bl); bi; bi = Nextitem(bl)) {
int virtual_base = 0;
unrollVirtualMethods(bi, parent, vm, default_director, virtual_destructor, virtual_base);
if (virtual_base) {
has_virtual = 1;
}
}
}
if (has_virtual) {
Setattr(n, "hasVirtual", "1");
}

View file

@ -1270,9 +1270,18 @@ public:
String *tm;
String *wrap_args;
String *return_type;
String *value = Getattr(n, "value");
String *storage = Getattr(n,"storage");
bool pure_virtual = false;
int status = SWIG_OK;
int idx;
if (Cmp(storage,"virtual") == 0) {
if (Cmp(value,"0") == 0) {
pure_virtual = true;
}
}
classname = Getattr(parent, "sym:name");
type = Getattr(n, "type");
name = Getattr(n, "name");
@ -1446,7 +1455,11 @@ public:
/* direct call to superclass if _up is set */
Printf(w->code, "if (__get_up()) {\n");
Printf(w->code, "return %s;\n", Swig_method_call(super,l));
if (pure_virtual) {
Printf(w->code, "throw SWIG_DIRECTOR_PURE_VIRTUAL_EXCEPTION();\n");
} else {
Printf(w->code, "return %s;\n", Swig_method_call(super,l));
}
Printf(w->code, "}\n");
/* check that have a wrapped Python object */