Fixes to support protected members with director, proper virtual member recognition and support of the nodirector feature

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5485 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2003-12-05 01:59:28 +00:00
commit 75c1713b2d
13 changed files with 380 additions and 37 deletions

View file

@ -308,7 +308,7 @@ static void add_symbols(Node *n) {
}
/* Don't add symbols for private/protected members */
if (inclass && (cplus_mode != CPLUS_PUBLIC)) {
if (inclass && (cplus_mode == CPLUS_PRIVATE)) {
while (n) {
Swig_symbol_add(0, n); /* Add to C symbol table */
if (cplus_mode == CPLUS_PRIVATE) {
@ -327,6 +327,9 @@ static void add_symbols(Node *n) {
n = nextSibling(n);
continue;
}
if (cplus_mode == CPLUS_PROTECTED) {
Setattr(n,"access", "protected");
}
decl = Getattr(n,"decl");
if (!SwigType_isfunction(decl)) {
symname = make_name(Getattr(n,"name"),0);
@ -3506,9 +3509,11 @@ def_args : EQUAL definetype {
Node *n = Swig_symbol_clookup($3.id,0);
if (n) {
String *q = Swig_symbol_qualified(n);
if (Getattr(n,"access")) {
if (cplus_mode == CPLUS_PUBLIC) {
Swig_warning(WARN_PARSE_PRIVATE, cparse_file, cparse_line,"'%s' is private in this context.\n", $3.id);
String *a = Getattr(n,"access");
if (a && (Strncmp(a,"private",7) == 0)) {
if (cplus_mode != CPLUS_PRIVATE) {
Swig_warning(WARN_PARSE_PRIVATE, cparse_file,
cparse_line,"'%s' is %s in this context.\n", q, a);
Swig_warning(WARN_PARSE_BAD_DEFAULT, cparse_file, cparse_line,"Can't set default argument value (ignored)\n");
}
$$.val = 0;
@ -4314,7 +4319,9 @@ expr : exprnum { $$ = $1; }
/* Check if value is in scope */
n = Swig_symbol_clookup($1,0);
if (n) {
if (Getattr(n,"access") && (cplus_mode == CPLUS_PUBLIC)) {
String *a = Getattr(n,"access");
if (a && (Strncmp(a, "private", 7) == 0)
&& (cplus_mode != CPLUS_PRIVATE)) {
Swig_warning(WARN_PARSE_PRIVATE,cparse_file, cparse_line, "'%s' is private in this context.\n", $1);
$$.type = T_ERROR;
} else {

View file

@ -19,6 +19,7 @@
char cvsroot_allocate_cxx[] = "$Header$";
#include "swigmod.h"
#include "utils.h"
static int virtual_elimination_mode = 0; /* set to 0 on default */
/* Set virtual_elimination_mode */
@ -93,6 +94,7 @@ class Allocate : public Dispatcher {
(checkAttribute(temp, "type", type)) &&
(!Strcmp(local_decl, base_decl)) ) {
// Indicate a virtual method in the derived class, that is, not the virtual method definition in a base class
Setattr(c, "storage", "virtual");
Setattr(c, "virtual:derived", "1");
if (virtual_elimination_mode)
Setattr(c, "feature:ignore", "1");
@ -146,7 +148,8 @@ class Allocate : public Dispatcher {
bases = Getattr(classnode, "bases");
if (!bases) return 0;
if (checkAttribute(member, "storage", "virtual")) {
//if (checkAttribute(member, "storage", "virtual"))
{
if (function_is_defined_in_bases(member, bases))
defined = 1;
}
@ -318,7 +321,7 @@ class Allocate : public Dispatcher {
{
for (int i = 0; i < Len(methods); ) {
Node *n = Getitem(methods,i);
if (checkAttribute(n,"access","protected") || checkAttribute(n,"access","private")) {
if (!is_public(n)) {
Delitem(methods,i);
continue;
}
@ -490,8 +493,8 @@ public:
if (inclass) {
/* check whether the member node n is defined in class node inclass's bases */
if (checkAttribute(n, "storage", "virtual"))
class_member_is_defined_in_bases(n, inclass);
// if (checkAttribute(n, "storage", "virtual"))
class_member_is_defined_in_bases(n, inclass);
/* Check to see if this is a static member or not. If so, we add an attribute
cplus:staticbase that saves the current class */

View file

@ -15,8 +15,17 @@
char cvsroot_lang_cxx[] = "$Header$";
#include "swigmod.h"
#include "utils.h"
#include <ctype.h>
static int director_protected_mode = 0; /* set to 0 on default */
/* Set director_protected_mode */
void Wrapper_director_protected_mode_set(int flag) {
director_protected_mode = flag;
}
/* Some status variables used during parsing */
static int InClass = 0; /* Parsing C++ or not */
@ -689,7 +698,7 @@ int Language::cDeclaration(Node *n) {
SwigType *ty, *fullty;
if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP;
if (Cmp(storage,"typedef") == 0) {
Swig_save("cDeclaration",n,"type",NIL);
SwigType *t = Copy(type);
@ -1421,27 +1430,27 @@ int Language::unrollVirtualMethods(Node *n,
// find the methods that need directors
classname = Getattr(n, "name");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
if (!Cmp(Getattr(ni, "feature:nodirector"), "1")) continue;
nodeType = Getattr(ni, "nodeType");
storage = Getattr(ni, "storage");
decl = Getattr(ni, "decl");
if (!Cmp(nodeType, "cdecl") && SwigType_isfunction(decl)) {
int is_virtual = storage && !Cmp(storage, "virtual");
String* access = Getattr(ni, "access");
if (!access || !Cmp(access, "public")) {
if (is_virtual) {
String *method_id;
String *name = Getattr(ni, "name");
method_id = NewStringf("%s|%s", name, decl);
String *fqname = NewString("");
Printf(fqname, "%s::%s", classname, name);
Hash *item = NewHash();
Setattr(item, "fqName", fqname);
Setattr(item, "methodNode", ni);
Setattr(vm, method_id, item);
Delete(fqname);
Delete(item);
Delete(method_id);
}
if (is_virtual &&
(is_public(ni) || (is_protected(ni) && director_protected_mode))) {
Setattr(ni, "feature:director", "1");
String *method_id;
String *name = Getattr(ni, "name");
method_id = NewStringf("%s|%s", name, decl);
String *fqname = NewString("");
Printf(fqname, "%s::%s", classname, name);
Hash *item = NewHash();
Setattr(item, "fqName", fqname);
Setattr(item, "methodNode", ni);
Setattr(vm, method_id, item);
Delete(fqname);
Delete(item);
Delete(method_id);
}
}
else if (!Cmp(nodeType, "destructor")) {
@ -1504,8 +1513,7 @@ int Language::classDirectorConstructors(Node *n) {
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
nodeType = Getattr(ni, "nodeType");
if (!Cmp(nodeType, "constructor")) {
String* access = Getattr(ni, "access");
if (!access || !Cmp(access, "public")) {
if (is_public(ni)) {
classDirectorConstructor(ni);
constructor = 1;
}
@ -1637,7 +1645,7 @@ int Language::classDeclaration(Node *n) {
ClassType = NewStringf("%s %s", kind, classname);
}
Setattr(n,"classtype", SwigType_namestr(ClassType));
Setattr(n,"classtypeobj", Copy(ClassType));
InClass = 1;
CurrentClass = n;

View file

@ -12,6 +12,8 @@
char cvsroot_python_cxx[] = "$Header$";
#include "swigmod.h"
#include "utils.h"
#ifndef MACSWIG
#include "swigconfig.h"
@ -68,6 +70,8 @@ Python Options (available with -python)\n\
-noexcept - No automatic exception handling\n\
-noproxy - Don't generate proxy classes \n\n";
extern void Wrapper_director_protected_mode_set(int);
class PYTHON : public Language {
public:
@ -79,6 +83,8 @@ public:
SWIG_library_directory("python");
Wrapper_director_protected_mode_set(1);
for (int i = 1; i < argc; i++) {
if (argv[i]) {
if(strcmp(argv[i],"-interface") == 0) {
@ -122,6 +128,8 @@ public:
classic = 0;
modern = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-nodirprot") == 0) {
Wrapper_director_protected_mode_set(0);
} else if (strcmp(argv[i],"-help") == 0) {
fputs(usage,stderr);
} else if (strcmp (argv[i], "-ldflags") == 0) {
@ -1304,8 +1312,15 @@ public:
/* declare Python return value */
Wrapper_add_local(w, "result", "PyObject *result");
/* direct call to superclass if _up is set */
Printf(w->code, "if (swig_get_up()) {\n");
if (is_protected(n)) {
Printf(w->code, "PyObject *obj = PyObject_GetAttrString(swig_get_self(), \"%s\");\n",
Getattr(n,"sym:name"));
Printf(w->code, "if (!obj) {\n");
} else {
Printf(w->code, "if (swig_get_up()) {\n");
}
if (pure_virtual) {
Printf(w->code, "throw Swig::DirectorPureVirtualException();\n");
} else {

View file

@ -24,6 +24,7 @@
char cvsroot_typepass_cxx[] = "$Header$";
#include "swigmod.h"
#include "utils.h"
struct normal_node {
Symtab *symtab;
@ -799,7 +800,7 @@ public:
ns = 0;
}
if (!ns) {
if (!Getattr(n,"access") || ((Strcmp(Getattr(n,"access"),"public") == 0))) {
if (is_public(n)) {
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n,"uname")));
}
} else {

View file

@ -0,0 +1,35 @@
#ifndef __Modules_utils_h__
#define __Modules_utils_h__
inline
int is_public(Node* n)
{
String* access = Getattr(n, "access");
return !access || !Cmp(access, "public");
}
inline
int is_private(Node* n)
{
String* access = Getattr(n, "access");
return access && !Cmp(access, "private");
}
inline
int is_protected(Node* n)
{
String* access = Getattr(n, "access");
return access && !Cmp(access, "protected");
}
inline
int is_member_director(Node* classnode, Node* member)
{
int class_director = !Cmp(Getattr(classnode,"feature:director"), "1");
int cdecl_nodirector = !Cmp(Getattr(member,"feature:nodirector"),"1");
return class_director && !cdecl_nodirector;
}
#endif //__Modules_utils_h__