From c41374becccbdfec452a9577a0dd3a63e7c78316 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Wed, 10 Dec 2003 23:10:31 +0000 Subject: [PATCH] %rename(x) Foo::y(); %inline %{ class Foo { protected: void x(); public: void y(); }; %} will work in plain or plain director mode, but it will complain the same as before with director protected support. The reason is that the parser emmits the warning, and at that stage it is not possible to decide if the protected Foo::x() could or not conflict with the renamed Foo::y(), since Foo::x() could be virtual, even when no "virtual" attribute is used. Core: parser.y: Detect the dirprot mode and prevents the generation of protected symbols at the parsing stage. lang.cxx: Export the director_protected_mode for parser.y and the director protected member detection is much cleaner. main.cxx: Fix the -dirprot flag, it was working in SWIG_FEATURE but not in the command line.(minor thing not relate to the error). swigmod.h: added Lang::dirprot_mode() for cleaner detection. utils.cxx: is_member_director() centralizes and improve the test. Test suite: protected_rename.i: added %inline, so it can compile now. director_protected.i: more cases, checking using %rename. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5530 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/director_protected.i | 21 ++++++++++++- Examples/test-suite/protected_rename.i | 2 ++ Source/CParse/parser.y | 40 +++++++++++++++++------- Source/Modules/lang.cxx | 31 ++++++++++++------ Source/Modules/main.cxx | 2 ++ Source/Modules/swigmod.h | 9 ++++-- Source/Modules/utils.cxx | 12 +++++-- 7 files changed, 89 insertions(+), 28 deletions(-) diff --git a/Examples/test-suite/director_protected.i b/Examples/test-suite/director_protected.i index 541d1db07..69ce58e87 100644 --- a/Examples/test-suite/director_protected.i +++ b/Examples/test-suite/director_protected.i @@ -12,6 +12,8 @@ %newobject *::create(); +%rename(a) Bar::hello; + %inline { class Foo { public: @@ -20,12 +22,20 @@ public: return "Foo::pong();" + ping(); } protected: + Foo() {} virtual std::string ping() = 0; + virtual std::string pang() + { + return "Foo::pang();"; + } + void hellom() {} - virtual void used() {} + virtual std::string used() { + return pang() + pong(); + } }; class Bar : public Foo @@ -48,9 +58,18 @@ protected: std::string ping() { return "Bar::ping();"; }; + + enum Hello {hola, chao}; + + static int a; + static const int b; int hi; void him() {} + +private: + int c; + }; diff --git a/Examples/test-suite/protected_rename.i b/Examples/test-suite/protected_rename.i index b5cc9b689..9728df1f0 100644 --- a/Examples/test-suite/protected_rename.i +++ b/Examples/test-suite/protected_rename.i @@ -8,6 +8,7 @@ %rename(x) Foo::y(); +%inline %{ class Foo { protected: int x; @@ -15,3 +16,4 @@ public: void y(); }; +%} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index d91b59635..b22bca9bb 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -49,6 +49,11 @@ extern String *scanner_ccode; extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms); extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms); +extern int Swig_need_protected(); + + + + /* NEW Variables */ extern void generate_all(Node *); @@ -68,6 +73,7 @@ static char *last_cpptype = 0; static int inherit_list = 0; static Parm *template_parameters = 0; static int extendmode = 0; +static int dirprot_mode = 0; /* ----------------------------------------------------------------------------- * Assist Functions @@ -150,6 +156,19 @@ static Node *copy_node(Node *n) { return nn; } +/* Detects when we need to record protected member information.*/ +static int need_protected(Node* n) +{ + if (!(Swig_need_protected() || dirprot_mode)) return 0; + + // + // Here detect if 'n' is a function. + // + return (Strcmp(nodeType(n),"cdecl") == 0) + && (Len(Getattr(n,"decl")) > 0); +} + + /* ----------------------------------------------------------------------------- * Variables * ----------------------------------------------------------------------------- */ @@ -315,11 +334,7 @@ static void add_symbols(Node *n) { if (inclass && (cplus_mode == CPLUS_PRIVATE)) { while (n) { Swig_symbol_add(0, n); /* Add to C symbol table */ - if (cplus_mode == CPLUS_PRIVATE) { - Setattr(n,"access", "private"); - } else { - Setattr(n,"access", "protected"); - } + Setattr(n,"access", "private"); if (add_only_one) break; n = nextSibling(n); } @@ -328,15 +343,14 @@ static void add_symbols(Node *n) { while (n) { String *symname; if (inclass && (cplus_mode == CPLUS_PROTECTED)) { - if (Strcmp(nodeType(n),"constructor") == 0) { - if (!Getattr(n,"access")) { - Swig_symbol_add(0, n); /* Add to C symbol table */ - Setattr(n,"access", "protected"); - } + Setattr(n,"access", "protected"); + if (!need_protected(n)) { + /* Only add to C symbol table and continue */ + Swig_symbol_add(0, n); + if (add_only_one) break; n = nextSibling(n); continue; } - Setattr(n,"access", "protected"); } if (Getattr(n,"sym:name")) { n = nextSibling(n); @@ -385,7 +399,7 @@ static void add_symbols(Node *n) { Setattr(n,"sym:name",symname); } else if ((Strcmp(nodeType(n),"template") == 0) && (Strcmp(Getattr(n,"templatetype"),"cdecl") == 0)) { Setattr(n,"sym:name",symname); - } else { + } else { String *e = NewString(""); Printf(e,"Identifier '%s' redeclared (ignored).", symname); if (Cmp(symname,Getattr(n,"name"))) { @@ -1390,6 +1404,8 @@ module_directive: MODULE options idstring { $$ = new_node("module"); Setattr($$,"name",$3); if ($2) Setattr($$,"options",$2); + if ($2 && Getattr($2,"directors") && Getattr($2,"dirprot")) + dirprot_mode = 1; if (!ModuleName) ModuleName = NewString($3); if (!module_node) module_node = $$; } diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 5bb8bb54b..719b5fcf8 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -23,6 +23,14 @@ static int director_protected_mode = 0; /* set to 0 on default */ void Wrapper_director_protected_mode_set(int flag) { director_protected_mode = flag; } + +extern "C" { + int Swig_need_protected() + { + return director_protected_mode; + } +} + /* Some status variables used during parsing */ @@ -699,10 +707,7 @@ int Language::cDeclaration(Node *n) { if (CurrentClass && (cplus_mode == CPLUS_PRIVATE)) return SWIG_NOWRAP; if (CurrentClass && (cplus_mode == CPLUS_PROTECTED) && - (!directors || - !director_protected_mode || - Cmp(storage,"virtual") || - !is_member_director(CurrentClass,n))) return SWIG_NOWRAP; + (!dirprot_mode() || !is_member_director(CurrentClass,n))) return SWIG_NOWRAP; if (Cmp(storage,"typedef") == 0) { Swig_save("cDeclaration",n,"type",NIL); @@ -1442,7 +1447,7 @@ int Language::unrollVirtualMethods(Node *n, if (!Cmp(nodeType, "cdecl") && SwigType_isfunction(decl)) { int is_virtual = storage && !Cmp(storage, "virtual"); if (is_virtual && - (is_public(ni) || (is_protected(ni) && director_protected_mode))) { + (is_public(ni) || (dirprot_mode() && is_protected(ni)))) { Setattr(ni, "feature:director", "1"); String *method_id; String *name = Getattr(ni, "name"); @@ -1720,7 +1725,7 @@ int Language::classHandler(Node *n) { classDirectorDisown(n); /* emit all the protected virtual members as needed */ - if (director_protected_mode) { + if (dirprot_mode()) { Node *vtable = Getattr(n, "vtable"); String* symname = Getattr(n, "sym:name"); Node *item; @@ -2196,6 +2201,14 @@ void Language::allow_directors(int val) { directors = val; } +/* ----------------------------------------------------------------------------- + * Language::directorsEnabled() + * ----------------------------------------------------------------------------- */ + +int Language::directorsEnabled() const { + return directors && CPlusPlus; +} + /* ----------------------------------------------------------------------------- * Language::allow_dirprot() * ----------------------------------------------------------------------------- */ @@ -2205,11 +2218,11 @@ void Language::allow_dirprot(int val) { } /* ----------------------------------------------------------------------------- - * Language::directorsEnabled() + * Language::dirprot_mode() * ----------------------------------------------------------------------------- */ -int Language::directorsEnabled() const { - return directors && CPlusPlus; +int Language::dirprot_mode() const { + return directorsEnabled() ? director_protected_mode : 0; } /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 855135ac8..ff948b279 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -372,8 +372,10 @@ int SWIG_main(int argc, char *argv[], Language *l) { Swig_mark_arg(i); } else if (strcmp(argv[i],"-dirprot") == 0) { Wrapper_director_protected_mode_set(1); + Swig_mark_arg(i); } else if (strcmp(argv[i],"-nodirprot") == 0) { Wrapper_director_protected_mode_set(0); + Swig_mark_arg(i); } else if (strcmp(argv[i],"-small") == 0) { Wrapper_compact_print_mode_set(1); Wrapper_virtual_elimination_mode_set(1); diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index ddeda1f07..0360d9c3e 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -214,12 +214,15 @@ public: /* Allow director related code generation */ void allow_directors(int val = 1); - /* Allow director protected members related code generation */ - void allow_dirprot(int val = 1); - /* Return true if directors are enabled */ int directorsEnabled() const; + /* Allow director protected members related code generation */ + void allow_dirprot(int val = 1); + + /* Returns the dirprot mode */ + int dirprot_mode() const; + /* Set none comparison string */ void setSubclassInstanceCheck(String *s); diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx index cb7351597..3a4cd66b5 100644 --- a/Source/Modules/utils.cxx +++ b/Source/Modules/utils.cxx @@ -21,9 +21,15 @@ int is_protected(Node* n) int is_member_director(Node* parentnode, Node* member) { - int parent_director = parentnode && checkAttribute(parentnode,"feature:director","1"); - int cdecl_nodirector = checkAttribute(member,"feature:nodirector","1"); - return parent_director && !cdecl_nodirector; + if (checkAttribute(member,"director","1")) return 1; + if (parentnode && checkAttribute(member, "storage", "virtual")) { + int parent_director = checkAttribute(parentnode,"feature:director","1"); + int cdecl_director = parent_director || checkAttribute(member,"feature:director","1"); + int cdecl_nodirector = checkAttribute(member,"feature:nodirector","1"); + return cdecl_director && !cdecl_nodirector; + } else { + return 0; + } } int is_member_director(Node* member)