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)