added support for friend declarations and clean/fix the

unrollVirtualMethods for the error shown in the director_redefined.i
example.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5621 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-01-13 01:12:53 +00:00
commit 66c06af171
2 changed files with 34 additions and 30 deletions

View file

@ -25,7 +25,7 @@
struct B : A struct B : A
{ {
virtual int get_val(int a) int get_val(int a)
{ {
return 1; return 1;
} }

View file

@ -703,11 +703,21 @@ int Language::cDeclaration(Node *n) {
Node *over; Node *over;
File *f_header = 0; File *f_header = 0;
SwigType *ty, *fullty; SwigType *ty, *fullty;
/* discarts nodes following the access control rules */
if (CurrentClass && (cplus_mode == CPLUS_PRIVATE)) return SWIG_NOWRAP; if (cplus_mode != CPLUS_PUBLIC) {
if (CurrentClass && (cplus_mode == CPLUS_PROTECTED) && /* except for friends, they are not affected by access control */
(!dirprot_mode() || !is_member_director(CurrentClass,n))) return SWIG_NOWRAP; int isfriend = storage && (Cmp(storage,"friend") == 0);
if (!isfriend) {
if (cplus_mode == CPLUS_PRIVATE) {
return SWIG_NOWRAP;
} else {
/* and for protected members, we check what director needs */
if (!(dirprot_mode() && is_member_director(CurrentClass,n)))
return SWIG_NOWRAP;
}
}
}
if (Cmp(storage,"typedef") == 0) { if (Cmp(storage,"typedef") == 0) {
Swig_save("cDeclaration",n,"type",NIL); Swig_save("cDeclaration",n,"type",NIL);
@ -719,11 +729,7 @@ int Language::cDeclaration(Node *n) {
} }
Swig_restore(n); Swig_restore(n);
return SWIG_OK; return SWIG_OK;
} else if (Cmp(storage,"friend") == 0) { }
Swig_warning(WARN_LANG_FRIEND_IGNORE, Getfile(n), Getline(n),
"friend function '%s' ignored.\n", name);
return SWIG_NOWRAP;
}
/* If in import mode, we proceed no further */ /* If in import mode, we proceed no further */
if (ImportMode) return SWIG_NOWRAP; if (ImportMode) return SWIG_NOWRAP;
@ -879,6 +885,8 @@ Language::functionHandler(Node *n) {
String *storage = Getattr(n,"storage"); String *storage = Getattr(n,"storage");
if (Cmp(storage,"static") == 0) { if (Cmp(storage,"static") == 0) {
staticmemberfunctionHandler(n); staticmemberfunctionHandler(n);
} else if (Cmp(storage,"friend") == 0) {
globalfunctionHandler(n);
} else { } else {
memberfunctionHandler(n); memberfunctionHandler(n);
} }
@ -1426,7 +1434,6 @@ int Language::unrollVirtualMethods(Node *n,
int &virtual_destructor) { int &virtual_destructor) {
Node *ni; Node *ni;
String *nodeType; String *nodeType;
String *storage;
String *classname; String *classname;
String *decl; String *decl;
// recurse through all base classes to build the vtable // recurse through all base classes to build the vtable
@ -1440,35 +1447,32 @@ int Language::unrollVirtualMethods(Node *n,
// find the methods that need directors // find the methods that need directors
classname = Getattr(n, "name"); classname = Getattr(n, "name");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
if (!Cmp(Getattr(ni, "feature:nodirector"), "1")) continue; /* we only need to check the virtual members */
if (!checkAttribute(ni, "storage", "virtual")) continue;
nodeType = Getattr(ni, "nodeType"); nodeType = Getattr(ni, "nodeType");
storage = Getattr(ni, "storage"); /* we need to add only the methods(cdecl), no destructors */
decl = Getattr(ni, "decl"); if (Cmp(nodeType, "cdecl") == 0 &&
if (!Cmp(nodeType, "cdecl") && SwigType_isfunction(decl)) { !checkAttribute(ni, "feature:nodirector", "1")) {
int is_virtual = storage && !Cmp(storage, "virtual"); decl = Getattr(ni, "decl");
if (is_virtual && /* extra check for function type and proper access */
if (SwigType_isfunction(decl) &&
(is_public(ni) || (dirprot_mode() && is_protected(ni)))) { (is_public(ni) || (dirprot_mode() && is_protected(ni)))) {
Setattr(ni, "feature:director", "1");
String *method_id;
String *name = Getattr(ni, "name"); String *name = Getattr(ni, "name");
method_id = NewStringf("%s|%s", name, decl); String *local_decl = SwigType_typedef_resolve_all(decl);
String *fqname = NewString(""); String *method_id = NewStringf("%s|%s", name, local_decl);
Printf(fqname, "%s::%s", classname, name); String *fqname = NewStringf("%s::%s", classname, name);
Hash *item = NewHash(); Hash *item = NewHash();
Setattr(ni, "feature:director", "1");
Setattr(item, "fqName", fqname); Setattr(item, "fqName", fqname);
Setattr(item, "methodNode", ni); Setattr(item, "methodNode", ni);
Setattr(vm, method_id, item); Setattr(vm, method_id, item);
Delete(fqname); Delete(fqname);
Delete(item); Delete(item);
Delete(method_id); Delete(method_id);
Delete(local_decl);
} }
} } else if (Cmp(nodeType, "destructor") == 0) {
else if (!Cmp(nodeType, "destructor")) { virtual_destructor = 1;
if (storage && !Cmp(storage, "virtual")) {
virtual_destructor = 1;
}
}
else {
} }
} }
return SWIG_OK; return SWIG_OK;