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:
parent
46d70e8e1f
commit
75c1713b2d
13 changed files with 380 additions and 37 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
35
SWIG/Source/Modules/utils.h
Normal file
35
SWIG/Source/Modules/utils.h
Normal 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__
|
||||
Loading…
Add table
Add a link
Reference in a new issue